数字货币开发教程的智能合约demo解析

区块链爱好者(QQ:53016353)
代码片

/*  
Copyright IBM Corp. 2016 All Rights Reserved.  
Licensed under the Apache License, Version 2.0 (the "License");  
you may not use this file except in compliance with the License.  
You may obtain a copy of the License at  
         http://www.apache.org/licenses/LICENSE-2.0  
Unless required by applicable law or agreed to in writing, software  
distributed under the License is distributed on an "AS IS" BASIS,  
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
See the License for the specific language governing permissions and  
limitations under the License.  
*/  
  
package main  
  
//WARNING - this chaincode's ID is hard-coded in chaincode_example04 to illustrate one way of  
//calling chaincode from a chaincode. If this example is modified, chaincode_example04.go has  
//to be modified as well with the new ID of chaincode_example02.  
//chaincode_example05 show's how chaincode ID can be passed in as a parameter instead of  
//hard-coding.  
  
import (  
    "errors"  
    "fmt"  
    "strconv"  
  
    "github.com/hyperledger/fabric/core/chaincode/shim"  
)  
  
// SimpleChaincode example simple Chaincode implementation  
type SimpleChaincode struct {  
}  
  
func (t *SimpleChaincode) Init(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {  
    var A, B string    // Entities  
    var Aval, Bval int // Asset holdings  
    var err error  
  
    if len(args) != 4 {  
        return nil, errors.New("Incorrect number of arguments. Expecting 4")  
    }  
  
    // Initialize the chaincode  
    A = args[0]  
    Aval, err = strconv.Atoi(args[1])  
    if err != nil {  
        return nil, errors.New("Expecting integer value for asset holding")  
    }  
    B = args[2]  
    Bval, err = strconv.Atoi(args[3])  
    if err != nil {  
        return nil, errors.New("Expecting integer value for asset holding")  
    }  
    fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)  
  
    // Write the state to the ledger  
    err = stub.PutState(A, []byte(strconv.Itoa(Aval)))  
    if err != nil {  
        return nil, err  
    }  
  
    err = stub.PutState(B, []byte(strconv.Itoa(Bval)))  
    if err != nil {  
        return nil, err  
    }  
  
    return nil, nil  
}  
  
// Transaction makes payment of X units from A to B  
func (t *SimpleChaincode) Invoke(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {  
    if function == "delete" {  
        // Deletes an entity from its state  
        return t.delete(stub, args)  
    }  
  
    var A, B string    // Entities  
    var Aval, Bval int // Asset holdings  
    var X int          // Transaction value  
    var err error  
  
    if len(args) != 3 {  
        return nil, errors.New("Incorrect number of arguments. Expecting 3")  
    }  
  
    A = args[0]  
    B = args[1]  
  
    // Get the state from the ledger  
    // TODO: will be nice to have a GetAllState call to ledger  
    Avalbytes, err := stub.GetState(A)  
    if err != nil {  
        return nil, errors.New("Failed to get state")  
    }  
    if Avalbytes == nil {  
        return nil, errors.New("Entity not found")  
    }  
    Aval, _ = strconv.Atoi(string(Avalbytes))  
  
    Bvalbytes, err := stub.GetState(B)  
    if err != nil {  
        return nil, errors.New("Failed to get state")  
    }  
    if Bvalbytes == nil {  
        return nil, errors.New("Entity not found")  
    }  
    Bval, _ = strconv.Atoi(string(Bvalbytes))  
  
    // Perform the execution  
    X, err = strconv.Atoi(args[2])  
    Aval = Aval - X  
    Bval = Bval + X  
    fmt.Printf("Aval = %d, Bval = %d\n", Aval, Bval)  
  
    // Write the state back to the ledger  
    err = stub.PutState(A, []byte(strconv.Itoa(Aval)))  
    if err != nil {  
        return nil, err  
    }  
  
    err = stub.PutState(B, []byte(strconv.Itoa(Bval)))  
    if err != nil {  
        return nil, err  
    }  
  
    return nil, nil  
}  
  
// Deletes an entity from state  
func (t *SimpleChaincode) delete(stub *shim.ChaincodeStub, args []string) ([]byte, error) {  
    if len(args) != 1 {  
        return nil, errors.New("Incorrect number of arguments. Expecting 1")  
    }  
  
    A := args[0]  
  
    // Delete the key from the state in ledger  
    err := stub.DelState(A)  
    if err != nil {  
        return nil, errors.New("Failed to delete state")  
    }  
  
    return nil, nil  
}  
  
// Query callback representing the query of a chaincode  
func (t *SimpleChaincode) Query(stub *shim.ChaincodeStub, function string, args []string) ([]byte, error) {  
    if function != "query" {  
        return nil, errors.New("Invalid query function name. Expecting \"query\"")  
    }  
    var A string // Entities  
    var err error  
  
    if len(args) != 1 {  
        return nil, errors.New("Incorrect number of arguments. Expecting name of the person to query")  
    }  
  
    A = args[0]  
  
    // Get the state from the ledger  
    Avalbytes, err := stub.GetState(A)  
    if err != nil {  
        jsonResp := "{\"Error\":\"Failed to get state for " + A + "\"}"  
        return nil, errors.New(jsonResp)  
    }  
  
    if Avalbytes == nil {  
        jsonResp := "{\"Error\":\"Nil amount for " + A + "\"}"  
        return nil, errors.New(jsonResp)  
    }  
  
    jsonResp := "{\"Name\":\"" + A + "\",\"Amount\":\"" + string(Avalbytes) + "\"}"  
    fmt.Printf("Query Response:%s\n", jsonResp)  
    return Avalbytes, nil  
}  
  
func main() {  
    err := shim.Start(new(SimpleChaincode))  
    if err != nil {  
        fmt.Printf("Error starting Simple chaincode: %s", err)  
    }  
}  

chaincode_example02  主要执行三个核心函数,init、invoke、query。
init函数在起始过程中初始化两个账户A,B,并且在A,B账户上发行一定数量的资产。
invoke函数在A、B上进行转账。
query函数查询A、B函数上的账户余额。
代码总体而言不是很复杂的,写类似的项目可以依着葫芦画瓢来做。

cli交互如下:

CORE_SECURITY_ENABLED=true CORE_SECURITY_PRIVACY=true peer chaincode deploy -u jim -n mycc -c '{"Function":"init", "Args": ["a","100", "b", "200"]}'  

rest可以使用postman,交互如下,

POST host:port/chaincode  
  
{  
  "jsonrpc": "2.0",  
  "method": "deploy",  
  "params": {  
    "type": 1,  
    "chaincodeID":{  
        "name": "mycc"  
    },  
    "ctorMsg": {  
        "function":"init",  
        "args":["a", "100", "b", "200"]  
    },  
    "secureContext": "jim"  
  },  
  "id": 1  
}  


cli与rest亲测可行。

你可能感兴趣的:(数字货币,数字货币开发)