added fixes to erc token samples and documentation

Signed-off-by: fraVlaca <ocsenarf@outlook.com>
This commit is contained in:
fraVlaca 2022-05-17 16:47:44 +01:00 committed by Dave Enyeart
parent 05791d30bc
commit 67a1166396
9 changed files with 131 additions and 46 deletions

View file

@ -133,6 +133,24 @@ fabric-ca-client enroll -u https://person5:person5pw@localhost:8054 --caname ca-
cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/person5@org2.example.com/msp/config.yaml"
```
## Initialize the contract
Once we created the identity of the minter we can now initialize the contract.
Note that we need to call the initialize function before being able to use any functions of the contract. Initialize() can be called only once.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```bash
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
```
We can then invoke the smart contract to initilize it
```bash
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n erc1155 -c '{"function":"Initialize","Args":["some name", "some symbol", "2"]}'
```
### Get account ID
Go back to the Org1 terminal, we'll set the following environment variables to operate the peer CLI as the minter identity from Org1.

View file

@ -810,7 +810,8 @@ func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface,
clientMSPID, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
return false, fmt.Errorf("failed to get MSPID: %v", err)
} else if clientMSPID != "Org1MSP" {
}
if clientMSPID != "Org1MSP" {
return false, fmt.Errorf("client is not authorized to initialize contract")
}
@ -818,7 +819,8 @@ func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface,
bytes, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get Name: %v", err)
} else if bytes != nil {
}
if bytes != nil {
return false, fmt.Errorf("contract options are already set, client is not authorized to change them")
}
@ -1123,7 +1125,8 @@ func checkInitialized(ctx contractapi.TransactionContextInterface) (bool, error)
tokenName, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get token name: %v", err)
} else if tokenName == nil {
}
if tokenName == nil {
return false, nil
}
return true, nil

View file

@ -98,9 +98,29 @@ Run the command below to copy the Node OU configuration file into the recipient
cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp/config.yaml"
```
## Initialize the contract
Once we created the identity of the minter we can now initialize the contract.
Note that we need to call the initialize function before being able to use any functions of the contract. Initialize() can be called only once.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
export TARGET_TLS_OPTIONS=(-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt")
```
We can then invoke the smart contract to initilize it
```
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc20 -c '{"function":"Initialize","Args":["some name", "some symbol", "2"]}'
```
## Mint some tokens
Now that we have created the identity of the minter, we can invoke the smart contract to mint some tokens.
Now that we have initialized the contract and created the identity of the minter, we can invoke the smart contract to mint some tokens.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```
export CORE_PEER_TLS_ENABLED=true

View file

@ -15,12 +15,12 @@ const nameKey = "name"
const symbolKey = "symbol"
const decimalsKey = "decimals"
const totalSupplyKey = "totalSupply"
// Define objectType names for prefix
const allowancePrefix = "allowance"
// Define key names for options
// SmartContract provides functions for transferring tokens between accounts
type SmartContract struct {
contractapi.Contract
@ -79,7 +79,7 @@ func (s *SmartContract) Mint(ctx contractapi.TransactionContextInterface, amount
currentBalance, _ = strconv.Atoi(string(currentBalanceBytes)) // Error handling not needed since Itoa() was used when setting the account balance, guaranteeing it was an integer.
}
updatedBalance,err := add(currentBalance, amount)
updatedBalance, err := add(currentBalance, amount)
if err != nil {
return err
}
@ -267,7 +267,7 @@ func (s *SmartContract) Transfer(ctx contractapi.TransactionContextInterface, re
// BalanceOf returns the balance of the given account
func (s *SmartContract) BalanceOf(ctx contractapi.TransactionContextInterface, account string) (int, error) {
//check if contract has been intilized first
initialized, err := checkInitialized(ctx)
if err != nil {
@ -581,14 +581,15 @@ func (s *SmartContract) Symbol(ctx contractapi.TransactionContextInterface) (str
// Set information for a token and intialize contract.
// param {String} name The name of the token
// param {String} symbol The symbol of the token
// param {String} decimals The name of the token
// param {String} decimals The decimals used for the token operations
func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface, name string, symbol string, decimals string) (bool, error) {
// Check minter authorization - this sample assumes Org1 is the central banker with privilege to intitialize contract
clientMSPID, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
return false, fmt.Errorf("failed to get MSPID: %v", err)
} else if clientMSPID != "Org1MSP" {
}
if clientMSPID != "Org1MSP" {
return false, fmt.Errorf("client is not authorized to initialize contract")
}
@ -596,7 +597,8 @@ func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface,
bytes, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get Name: %v", err)
}else if bytes != nil {
}
if bytes != nil {
return false, fmt.Errorf("contract options are already set, client is not authorized to change them")
}
@ -614,8 +616,8 @@ func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface,
if err != nil {
return false, fmt.Errorf("failed to set token name: %v", err)
}
return true, nil;
return true, nil
}
// Helper Functions
@ -686,7 +688,6 @@ func transferHelper(ctx contractapi.TransactionContextInterface, from string, to
return nil
}
// add two number checking for overflow
func add(b int, q int) (int, error) {
@ -694,7 +695,7 @@ func add(b int, q int) (int, error) {
var sum int
sum = q + b
if (sum < q) == (b > 0 && q > 0) {
if (sum < q) == (b >= 0 && q >= 0) {
return 0, fmt.Errorf("Math: addition overflow occurred %d + %d", b, q)
}
@ -706,12 +707,14 @@ func checkInitialized(ctx contractapi.TransactionContextInterface) (bool, error)
tokenName, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get token name: %v", err)
}else if (tokenName == nil){
return false , nil
}
return true , nil
}
if tokenName == nil {
return false, nil
}
return true, nil
}
// sub two number checking for overflow
func sub(b int, q int) (int, error) {
@ -720,7 +723,7 @@ func sub(b int, q int) (int, error) {
var diff int
diff = q - b
if (diff > q) == (b > 0 && q > 0) {
if (diff > q) == (b >= 0 && q >= 0) {
return 0, fmt.Errorf("Math: Subtraction overflow occurred %d - %d", b, q)
}

View file

@ -202,14 +202,14 @@ describe('Chaincode', () => {
describe('#Initialize', () => {
it('should work', async () => {
//we consider that is been already initialize in the before each statement
//we consider it has already been initialized in the before-each statement
sinon.assert.calledWith(mockStub.putState, 'name', Buffer.from('some name'));
sinon.assert.calledWith(mockStub.putState, 'symbol', Buffer.from('some symbol'));
sinon.assert.calledWith(mockStub.putState, 'decimals', Buffer.from('2'));
});
it('should failed if called a second time', async () => {
//we consider that is been already initialize in the before each statement
//we consider it has already been initialized in the before-each statement
await expect(await token.Initialize(ctx, 'some name', 'some symbol', '2'))
.to.be.rejectedWith(Error, 'contract options are already set, client is not authorized to change them');
});

View file

@ -98,9 +98,28 @@ Run the command below to copy the Node OU configuration file into the recipient
cp ${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml ${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp/config.yaml
```
## Initialize the contract
Once we created the identity of the minter we can now initialize the contract.
Note that we need to call the initialize function before being able to use any functions of the contract. Initialize() can be called only once.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
export TARGET_TLS_OPTIONS=(-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt")
```
We can then invoke the smart contract to initilize it
```
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_erc721 -c '{"function":"Initialize","Args":["some name", "some symbol", "2"]}'
```
## Mint a non-fungible token
Now that we have created the identity of the minter, we can invoke the smart contract to mint a non-fungible token.
Now that we have initialized the contract and created the identity of the minter, we can invoke the smart contract to mint a non-fungible token.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```
export CORE_PEER_TLS_ENABLED=true

View file

@ -64,7 +64,7 @@ func (c *TokenERC721Contract) BalanceOf(ctx contractapi.TransactionContextInterf
//check if contract has been intilized first
initialized, err := checkInitialized(ctx)
if err != nil {
panic("failed to check if contract ia already initialized:"+ err.Error())
panic("failed to check if contract ia already initialized:" + err.Error())
}
if !initialized {
panic("Contract options need to be set before calling any function, call Initialize() to initialize contract")
@ -240,7 +240,7 @@ func (c *TokenERC721Contract) IsApprovedForAll(ctx contractapi.TransactionContex
//check if contract has been intilized first
initialized, err := checkInitialized(ctx)
if err != nil {
return false,fmt.Errorf("failed to check if contract ia already initialized: %v", err)
return false, fmt.Errorf("failed to check if contract ia already initialized: %v", err)
}
if !initialized {
return false, fmt.Errorf("Contract options need to be set before calling any function, call Initialize() to initialize contract")
@ -277,7 +277,7 @@ func (c *TokenERC721Contract) GetApproved(ctx contractapi.TransactionContextInte
//check if contract has been intilized first
initialized, err := checkInitialized(ctx)
if err != nil {
return "false",fmt.Errorf("failed to check if contract ia already initialized: %v", err)
return "false", fmt.Errorf("failed to check if contract ia already initialized: %v", err)
}
if !initialized {
return "false", fmt.Errorf("Contract options need to be set before calling any function, call Initialize() to initialize contract")
@ -308,7 +308,6 @@ func (c *TokenERC721Contract) TransferFrom(ctx contractapi.TransactionContextInt
return false, fmt.Errorf("Contract options need to be set before calling any function, call Initialize() to initialize contract")
}
// Get ID of submitting client identity
sender64, err := ctx.GetClientIdentity().GetID()
if err != nil {
@ -480,7 +479,7 @@ func (c *TokenERC721Contract) TotalSupply(ctx contractapi.TransactionContextInte
//check if contract has been intilized first
initialized, err := checkInitialized(ctx)
if err != nil {
panic("failed to check if contract ia already initialized:"+ err.Error())
panic("failed to check if contract ia already initialized:" + err.Error())
}
if !initialized {
panic("Contract options need to be set before calling any function, call Initialize() to initialize contract")
@ -518,14 +517,16 @@ func (c *TokenERC721Contract) Initialize(ctx contractapi.TransactionContextInter
clientMSPID, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
return false, fmt.Errorf("failed to get clientMSPID: %v", err)
} else if clientMSPID != "Org1MSP" {
}
if clientMSPID != "Org1MSP" {
return false, fmt.Errorf("client is not authorized to set the name and symbol of the token")
}
bytes, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get Name: %v", err)
}else if bytes != nil {
}
if bytes != nil {
return false, fmt.Errorf("contract options are already set, client is not authorized to change them")
}
@ -558,7 +559,6 @@ func (c *TokenERC721Contract) MintWithTokenURI(ctx contractapi.TransactionContex
return nil, fmt.Errorf("Contract options need to be set before calling any function, call Initialize() to initialize contract")
}
// Check minter authorization - this sample assumes Org1 is the issuer with privilege to mint a new token
clientMSPID, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
@ -780,7 +780,8 @@ func checkInitialized(ctx contractapi.TransactionContextInterface) (bool, error)
tokenName, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get token name: %v", err)
}else if (tokenName == nil){
}
if tokenName == nil {
return false, nil
}
return true, nil

View file

@ -92,9 +92,28 @@ Run the command below to copy the Node OU configuration file into the recipient
cp "${PWD}/organizations/peerOrganizations/org2.example.com/msp/config.yaml" "${PWD}/organizations/peerOrganizations/org2.example.com/users/recipient@org2.example.com/msp/config.yaml"
```
## Initialize the contract
Once we created the identity of the minter we can now initialize the contract.
Note that we need to call the initialize function before being able to use any functions of the contract. Initialize() can be called only once.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_LOCALMSPID="Org1MSP"
export CORE_PEER_MSPCONFIGPATH=${PWD}/organizations/peerOrganizations/org1.example.com/users/minter@org1.example.com/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt
export CORE_PEER_ADDRESS=localhost:7051
export TARGET_TLS_OPTIONS=(-o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt")
```
We can then invoke the smart contract to initilize it
```
peer chaincode invoke "${TARGET_TLS_OPTIONS[@]}" -C mychannel -n token_utxo -c '{"function":"Initialize","Args":["some name", "some symbol", "2"]}'
```
## Mint some tokens
Now that we have created the identity of the minter, we can invoke the smart contract to mint some tokens.
Now that we have initialized the contract and created the identity of the minter, we can invoke the smart contract to mint some tokens.
Shift back to the Org1 terminal, we'll set the following environment variables to operate the `peer` CLI as the minter identity from Org1.
```
export CORE_PEER_TLS_ENABLED=true

View file

@ -123,7 +123,7 @@ func (s *SmartContract) Transfer(ctx contractapi.TransactionContextInterface, ut
Amount: amount,
}
totalInputAmount,err = add(totalInputAmount, amount)
totalInputAmount, err = add(totalInputAmount, amount)
utxoInputs[utxoInputKey] = utxoInput
}
@ -138,7 +138,7 @@ func (s *SmartContract) Transfer(ctx contractapi.TransactionContextInterface, ut
utxoOutputs[i].Key = fmt.Sprintf("%s.%d", txID, i)
totalOutputAmount,err = add(totalOutputAmount, utxoOutput.Amount)
totalOutputAmount, err = add(totalOutputAmount, utxoOutput.Amount)
}
// Validate total inputs equals total outputs
@ -309,12 +309,13 @@ func (s *SmartContract) Symbol(ctx contractapi.TransactionContextInterface) (str
// param {String} name The name of the token
// param {String} symbol The symbol of the token
func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface, name string, symbol string) (bool, error) {
// Check minter authorization - this sample assumes Org1 is the central banker with privilege to intitialize contract
clientMSPID, err := ctx.GetClientIdentity().GetMSPID()
if err != nil {
return false, fmt.Errorf("failed to get MSPID: %v", err)
} else if clientMSPID != "Org1MSP" {
}
if clientMSPID != "Org1MSP" {
return false, fmt.Errorf("client is not authorized to initialize contract")
}
@ -322,8 +323,9 @@ func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface,
bytes, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get Name: %v", err)
}else if bytes != nil {
return false, fmt.Errorf("contract options are already set, client is not authorized to change them")
}
if bytes != nil {
return false, fmt.Errorf("contract options are already set, client is not authorized to change them")
}
err = ctx.GetStub().PutState(nameKey, []byte(name))
@ -337,8 +339,8 @@ func (s *SmartContract) Initialize(ctx contractapi.TransactionContextInterface,
}
log.Printf("name: %v, symbol: %v", name, symbol)
return true, nil;
return true, nil
}
//Checks that contract options have been already initialized
@ -346,13 +348,13 @@ func checkInitialized(ctx contractapi.TransactionContextInterface) (bool, error)
tokenName, err := ctx.GetStub().GetState(nameKey)
if err != nil {
return false, fmt.Errorf("failed to get token name: %v", err)
}else if (tokenName == nil){
return false , nil
}
return true , nil
if tokenName == nil {
return false, nil
}
return true, nil
}
// add two number checking for overflow
func add(b int, q int) (int, error) {
@ -360,7 +362,7 @@ func add(b int, q int) (int, error) {
var sum int
sum = q + b
if (sum < q) == (b > 0 && q > 0) {
if (sum < q) == (b >= 0 && q >= 0) {
return 0, fmt.Errorf("Math: addition overflow occurred %d + %d", b, q)
}