在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
代币智能合约: package main /* // 安装智能合约 peer chaincode install -n token3 -v 1.0 -p chaincodedev/chaincode/token // 实例化智能合约 peer chaincode instantiate -C myc -n token3 -v 1.0 -c '{"Args":[""]}' -P "OR ('Org1MSP.member','Org2MSP.member')" // 创建平台账户 peer chaincode invoke -C myc -n token3 -c '{"function":"createAccount","Args":["coinbase"]}' // 查询平台账户 peer chaincode invoke -C myc -n token3 -v 1.0 -c '{"function":"showAccount","Args":["coinbase"]}' // 查询全部 peer chaincode invoke -C myc -n token3 -c '{"function":"balanceAll","Args":["coinbase"]}' // 给平台账户初始化币种以及储量 peer chaincode invoke -C myc -n token3 -c '{"function":"platFormTransferToken","Args":["Thyc Token","TLD","1000000","coinbase"]}' // 初始化另外一种代币 peer chaincode invoke -C myc -n token3 -c '{"function":"initCurrency","Args":["One Token","ONE","1000000","coinbase"]}' // 锁定 peer chaincode invoke -C myc -n token3 -c '{"function":"setLock","Args":["true"]}' // 解锁 peer chaincode invoke -C myc -n token3 -c '{"function":"setLock","Args":["false"]}' // 增发币 peer chaincode invoke -C myc -n token3 -c '{"function":"mintToken","Args":["TLD","5000","coinbase"]}' // 创建账户 peer chaincode invoke -C myc -n token3 -c '{"function":"createAccount","Args":["ming"]}' // 转账 peer chaincode invoke -C myc -n token3 -c '{"function":"transferToken","Args":["TLD","coinbase","ming","100","wzm","0.1"]}' // 平台转账 peer chaincode invoke -C myc -n token3 -c '{"function":"platFormTransferToken","Args":["TLD","coinbase","ming","100"]}' // 查询指定币种余额 peer chaincode invoke -C myc -n token3 -c '{"function":"balance","Args":["ming","TLD"]}' // 账号解冻 peer chaincode invoke -C myc -n token3 -c '{"function":"frozenAccount","Args":["ming","true"]}' -------------------------------------------------------------------------------------------------------------------------------------------- */ import ( "encoding/json" "fmt" "strconv" "github.com/hyperledger/fabric/core/chaincode/shim" pb "github.com/hyperledger/fabric/protos/peer" ) // 响应结构 type Msg struct { Data string `json:"data"` Code int `json:"code"` Msg string `json:"msg"` } // 资金结构 type Currency struct { TokenName string `json:"TokenName"` TokenSymbol string `json:"TokenSymbol"` TotalSupply float64 `json:"TotalSupply"` } // 账户结构 type Account struct { Name string `json:"Name"` Frozen bool `json:"Frozen"` BalanceOf map[string]float64 `json:"BalanceOf"` } // 代币结构 type Token struct { Lock bool `json:"Lock"` Currency map[string]Currency `json:"Currency"` } // ----------- const TokenKey = "Token" // Define the Smart Contract structure type SmartContract struct { } /** * 转账 * * @param currency 货币符号 * @param fromAddress 转出 * @param toAddress 转入 * @param amountValue 转账金额 * @param platformAddress 手续费接收地址 * @param serviceChargeValue 手续费 * */ func (token *Token) transfer(currency string, fromAddress *Account, toAddress *Account, value float64, platformAddress *Account, serviceChargeValue float64) []byte { var rev []byte if token.Lock { msg := &Msg{Data: "", Code: 0, Msg: "锁仓状态,停止一切转账活动"} rev, _ = json.Marshal(msg) return rev } if fromAddress.Frozen { msg := &Msg{Data: "", Code: 0, Msg: "From 账号冻结"} rev, _ = json.Marshal(msg) return rev } if toAddress.Frozen { msg := &Msg{Data: "", Code: 0, Msg: "To 账号冻结"} rev, _ = json.Marshal(msg) return rev } if !token.isCurrency(currency) { msg := &Msg{Data: "", Code: 0, Msg: "货币符号不存在"} rev, _ = json.Marshal(msg) return rev } // 余额需要大于等于 转账金额加上手续费 if (fromAddress.BalanceOf[currency] > 0) && (fromAddress.BalanceOf[currency] >= (value + serviceChargeValue)) { // from地址扣除金额 fromAddress.BalanceOf[currency] -= value // to地址增加金额 toAddress.BalanceOf[currency] += value // 来源地址扣手续费 fromAddress.BalanceOf[currency] -= serviceChargeValue // 平台地址增加手续费 platformAddress.BalanceOf[currency] += serviceChargeValue msg := &Msg{Data: "", Code: 1, Msg: "转账成功"} rev, _ = json.Marshal(msg) return rev } else { msg := &Msg{Data: "", Code: 0, Msg: "余额不足"} rev, _ = json.Marshal(msg) return rev } } // 平台转账 func (token *Token) platFormTransfer(currency string, fromAddress *Account, toAddress *Account, value float64) []byte { var rev []byte if token.Lock { msg := &Msg{Data: "", Code: 0, Msg: "锁仓状态,停止一切转账活动"} rev, _ = json.Marshal(msg) return rev } if fromAddress.Frozen { msg := &Msg{Data: "", Code: 0, Msg: "From 账号冻结"} rev, _ = json.Marshal(msg) return rev } if toAddress.Frozen { msg := &Msg{Data: "", Code: 0, Msg: "To 账号冻结"} rev, _ = json.Marshal(msg) return rev } if !token.isCurrency(currency) { msg := &Msg{Data: "", Code: 0, Msg: "货币符号不存在"} rev, _ = json.Marshal(msg) return rev } // 余额需要大于等于 转账金额加上手续费 if (fromAddress.BalanceOf[currency] > 0) && (fromAddress.BalanceOf[currency] >= value) { // from地址扣除金额 fromAddress.BalanceOf[currency] -= value // to地址增加金额 toAddress.BalanceOf[currency] += value msg := &Msg{Data: "", Code: 1, Msg: "转账成功"} rev, _ = json.Marshal(msg) return rev } else { msg := &Msg{Data: "", Code: 0, Msg: "余额不足"} rev, _ = json.Marshal(msg) return rev } } // 初始化代币(合约升级成功后需要再次调用该方法给代币初始化代币符号) func (token *Token) initialSupply(name string, symbol string, supply float64, account *Account) []byte { if _, ok := token.Currency[symbol]; ok { msg := &Msg{Data: "", Code: 0, Msg: "代币已经存在"} rev, _ := json.Marshal(msg) return rev } if account.BalanceOf[symbol] > 0 { token.Currency[symbol] = Currency{TokenName: name, TokenSymbol: symbol, TotalSupply: account.BalanceOf[symbol]} account.BalanceOf[symbol] = account.BalanceOf[symbol] msg := &Msg{Data: "", Code: 1, Msg: "代币符号初始化成功"} rev, _ := json.Marshal(msg) return rev } else { token.Currency[symbol] = Currency{TokenName: name, TokenSymbol: symbol, TotalSupply: supply} account.BalanceOf[symbol] = supply msg := &Msg{Data: "", Code: 1, Msg: "代币初始化成功"} rev, _ := json.Marshal(msg) return rev } } // 增发代币 func (token *Token) mint(currency string, amount float64, account *Account) []byte { if !token.isCurrency(currency) { msg := &Msg{Data: "", Code: 0, Msg: "货币符号不存在"} rev, _ := json.Marshal(msg) return rev } cur := token.Currency[currency] // 获取平台总资产 cur.TotalSupply += amount token.Currency[currency] = cur // 获取平台账户总资产 account.BalanceOf[currency] += amount msg := &Msg{Data: "", Code: 1, Msg: "代币增发成功"} rev, _ := json.Marshal(msg) return rev } // 回收代币 func (token *Token) burn(currency string, amount float64, account *Account) []byte { if !token.isCurrency(currency) { msg := &Msg{Data: "", Code: 0, Msg: "货币符号不存在"} rev, _ := json.Marshal(msg) return rev } if token.Currency[currency].TotalSupply >= amount { cur := token.Currency[currency] cur.TotalSupply -= amount token.Currency[currency] = cur account.BalanceOf[currency] -= amount msg := &Msg{Data: "", Code: 1, Msg: "代币回收成功"} rev, _ := json.Marshal(msg) return rev } else { msg := &Msg{Data: "", Code: 0, Msg: "代币回收失败,回收额度不足"} rev, _ := json.Marshal(msg) return rev } } // 是否是资产 func (token *Token) isCurrency(currency string) bool { if _, ok := token.Currency[currency]; ok { return true } else { return false } } // 设置仓库锁 func (token *Token) setLock(look bool) bool { token.Lock = look return token.Lock } // 资产 func (account *Account) balance(currency string) map[string]float64 { bal := map[string]float64{currency: account.BalanceOf[currency]} return bal } // 全部资产 func (account *Account) balanceAll() map[string]float64 { return account.BalanceOf } // -------------------------------------------------------------------------- // -------------------------实现Init-Query-Invoke方法------------------------- // -------------------------------------------------------------------------- // 初始化(目前这个初始化方法是没有做任何事情的) func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) pb.Response { token := &Token{Currency: map[string]Currency{}} tokenAsBytes, err := json.Marshal(token) err = stub.PutState(TokenKey, tokenAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("Init Token %s \n", string(tokenAsBytes)) } return shim.Success(nil) } // 执行(只写) func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) pb.Response { // Retrieve the requested Smart Contract function and arguments function, args := stub.GetFunctionAndParameters() // Route to the appropriate handler function to interact with the ledger appropriately if function == "initLedger" { // 初始化账本 return s.initLedger(stub, args) } else if function == "createAccount" { // 创建账户 return s.createAccount(stub, args) } else if function == "initCurrency" { // 初始化代币 return s.initCurrency(stub, args) } else if function == "setLock" { // 锁/解锁仓 return s.setLock(stub, args) } else if function == "transferToken" { // 转账 return s.transferToken(stub, args) } else if function == "platFormTransferToken" { // 平台转账 return s.platFormTransferToken(stub, args) } else if function == "frozenAccount" { // 冻结/解冻账户 return s.frozenAccount(stub, args) } else if function == "mintToken" { // 增发代币 return s.mintToken(stub, args) } else if function == "burnToken" { // 回收代币 return s.burnToken(stub, args) } else if function == "balance" { // 查询资产 return s.balance(stub, args) } else if function == "balanceAll" { // 查询全部资产 return s.balanceAll(stub, args) } else if function == "showAccount" { // 查询账户 return s.showAccount(stub, args) } else if function == "showToken" { // 查询代币 return s.showToken(stub, args) } return shim.Error("Invalid Smart Contract function name.") } // -------------------------------------------------------------------------- // -------------------------实现Init-Query-Invoke方法------------------------- // -------------------------------------------------------------------------- // 创建账户 func (s *SmartContract) createAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("Incorrect number of arguments. Expecting 1") } key := args[0] name := args[0] existAsBytes, err := stub.GetState(key) fmt.Printf("GetState(%s) %s \n", key, string(existAsBytes)) if string(existAsBytes) != "" { fmt.Println("Failed to create account, Duplicate key.") return shim.Error("Failed to create account, Duplicate key.") } account := Account{ Name: name, Frozen: false, BalanceOf: map[string]float64{}} accountAsBytes, _ := json.Marshal(account) err = stub.PutState(key, accountAsBytes) if err != nil { return shim.Error(err.Error()) } fmt.Printf("createAccount %s \n", string(accountAsBytes)) return shim.Success(accountAsBytes) } // 初始化账本 func (s *SmartContract) initLedger(stub shim.ChaincodeStubInterface, args []string) pb.Response { return shim.Success(nil) } // 查询代币 func (s *SmartContract) showToken(stub shim.ChaincodeStubInterface, args []string) pb.Response { tokenAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("GetState(%s)) %s \n", TokenKey, string(tokenAsBytes)) } return shim.Success(tokenAsBytes) } // 初始化货币 func (s *SmartContract) initCurrency(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 4 { return shim.Error("Incorrect number of arguments. Expecting 4") } // 代币名称 name := args[0] // 代币符号 symbol := args[1] // 发行额度 supply, _ := strconv.ParseFloat(args[2], 64) // 发行账户 account := args[3] coinbaseAsBytes, err := stub.GetState(account) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Coinbase before %s \n", string(coinbaseAsBytes)) coinbase := &Account{} json.Unmarshal(coinbaseAsBytes, &coinbase) token := Token{} existAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("GetState(%s)) %s \n", TokenKey, string(existAsBytes)) } json.Unmarshal(existAsBytes, &token) result := token.initialSupply(name, symbol, supply, coinbase) tokenAsBytes, _ := json.Marshal(token) err = stub.PutState(TokenKey, tokenAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("Init Token %s \n", string(tokenAsBytes)) } coinbaseAsBytes, _ = json.Marshal(coinbase) err = stub.PutState(account, coinbaseAsBytes) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Coinbase after %s \n", string(coinbaseAsBytes)) return shim.Success(result) } // 平台转账 func (s *SmartContract) platFormTransferToken(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 4 { return shim.Error("Incorrect number of arguments. Expecting 4") } currency := args[0] from := args[1] to := args[2] amount, _ := strconv.ParseFloat(args[3], 64) if amount <= 0 { return shim.Error("Incorrect number of amount") } fromAsBytes, err := stub.GetState(from) if err != nil { return shim.Error(err.Error()) } fmt.Printf("fromAccount %s \n", string(fromAsBytes)) fromAccount := &Account{} json.Unmarshal(fromAsBytes, &fromAccount) toAsBytes, err := stub.GetState(to) if err != nil { return shim.Error(err.Error()) } fmt.Printf("toAccount %s \n", string(toAsBytes)) toAccount := &Account{} json.Unmarshal(toAsBytes, &toAccount) tokenAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Token %s \n", string(tokenAsBytes)) token := Token{Currency: map[string]Currency{}} json.Unmarshal(tokenAsBytes, &token) result := token.platFormTransfer(currency, fromAccount, toAccount, amount) fmt.Printf("Result %s \n", string(result)) fromAsBytes, err = json.Marshal(fromAccount) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(from, fromAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("fromAccount %s \n", string(fromAsBytes)) } toAsBytes, err = json.Marshal(toAccount) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(to, toAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("toAccount %s \n", string(toAsBytes)) } return shim.Success(result) } // 转账 func (s *SmartContract) transferToken(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 6 { return shim.Error("Incorrect number of arguments. Expecting 6") } /** * @param currency 货币符号 * @param fromAddress 转出 * @param toAddress 转入 * @param amountValue 转账金额 * @param platformAddress 手续费接收地址 * @param serviceChargeValue 手续费 * */ // 币种 currency := args[0] // 转出地址 fromAddress := args[1] // 转入地址 toAddress := args[2] // 转账额度 amount, _ := strconv.ParseFloat(args[3], 64) // 手续费接收地址 platformAddress := args[4] // 手续费 serviceCharge, _ := strconv.ParseFloat(args[5], 64) if amount <= 0 { return shim.Error("Incorrect number of amount") } // 源地址对象 fromAsBytes, err := stub.GetState(fromAddress) if err != nil { return shim.Error(err.Error()) } fmt.Printf("fromAccount %s \n", string(fromAsBytes)) fromAccount := &Account{} json.Unmarshal(fromAsBytes, &fromAccount) // 目标地址对象 toAsBytes, err := stub.GetState(toAddress) if err != nil { return shim.Error(err.Error()) } fmt.Printf("toAccount %s \n", string(toAsBytes)) toAccount := &Account{} json.Unmarshal(toAsBytes, &toAccount) // 获取平台账户对象 platformAsBytes, err := stub.GetState(platformAddress) if err != nil { return shim.Error(err.Error()) } fmt.Printf("platformAccount %s \n", string(platformAsBytes)) platformAccount := &Account{} json.Unmarshal(platformAsBytes, &platformAccount) tokenAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Token %s \n", string(tokenAsBytes)) token := Token{Currency: map[string]Currency{}} json.Unmarshal(tokenAsBytes, &token) result := token.transfer(currency, fromAccount, toAccount, amount, platformAccount, serviceCharge) fmt.Printf("Result %s \n", string(result)) fromAsBytes, err = json.Marshal(fromAccount) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(fromAddress, fromAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("fromAccount %s \n", string(fromAsBytes)) } toAsBytes, err = json.Marshal(toAccount) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(toAddress, toAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("toAccount %s \n", string(toAsBytes)) } platformAsBytes, err = json.Marshal(platformAccount) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(platformAddress, platformAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("platformAccount %s \n", string(platformAsBytes)) } return shim.Success(result) } // 增发代币 func (s *SmartContract) mintToken(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 3 { return shim.Error("Incorrect number of arguments. Expecting 3") } currency := args[0] amount, _ := strconv.ParseFloat(args[1], 64) account := args[2] coinbaseAsBytes, err := stub.GetState(account) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("Coinbase before %s \n", string(coinbaseAsBytes)) } coinbase := &Account{} json.Unmarshal(coinbaseAsBytes, &coinbase) tokenAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Token before %s \n", string(tokenAsBytes)) token := Token{} json.Unmarshal(tokenAsBytes, &token) result := token.mint(currency, amount, coinbase) tokenAsBytes, err = json.Marshal(token) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(TokenKey, tokenAsBytes) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Token after %s \n", string(tokenAsBytes)) coinbaseAsBytes, _ = json.Marshal(coinbase) err = stub.PutState(account, coinbaseAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("Coinbase after %s \n", string(coinbaseAsBytes)) } fmt.Printf("mintToken %s \n", string(tokenAsBytes)) return shim.Success(result) } // 回收代币 func (s *SmartContract) burnToken(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 3 { return shim.Error("Incorrect number of arguments. Expecting 3") } currency := args[0] amount, _ := strconv.ParseFloat(args[1], 64) account := args[2] coinbaseAsBytes, err := stub.GetState(account) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("Coinbase before %s \n", string(coinbaseAsBytes)) } coinbase := &Account{} json.Unmarshal(coinbaseAsBytes, &coinbase) tokenAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Token before %s \n", string(tokenAsBytes)) token := Token{} json.Unmarshal(tokenAsBytes, &token) result := token.burn(currency, amount, coinbase) tokenAsBytes, err = json.Marshal(token) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(TokenKey, tokenAsBytes) if err != nil { return shim.Error(err.Error()) } fmt.Printf("Token after %s \n", string(tokenAsBytes)) coinbaseAsBytes, _ = json.Marshal(coinbase) err = stub.PutState(account, coinbaseAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("Coinbase after %s \n", string(coinbaseAsBytes)) } fmt.Printf("burnToken %s \n", string(tokenAsBytes)) return shim.Success(result) } // 设置锁或者解锁 func (s *SmartContract) setLock(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 1 { return shim.Error("Incorrect number of arguments. Expecting 2") } look := args[0] tokenAsBytes, err := stub.GetState(TokenKey) if err != nil { return shim.Error(err.Error()) } // fmt.Printf("setLock - begin %s \n", string(tokenAsBytes)) token := Token{} json.Unmarshal(tokenAsBytes, &token) if look == "true" { token.setLock(true) } else { token.setLock(false) } tokenAsBytes, err = json.Marshal(token) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(TokenKey, tokenAsBytes) if err != nil { return shim.Error(err.Error()) } fmt.Printf("setLock - end %s \n", string(tokenAsBytes)) msg := &Msg{Data: string(tokenAsBytes), Code: 1, Msg: "操作成功"} rev, _ := json.Marshal(msg) return shim.Success(rev) } // 冻结账户 func (s *SmartContract) frozenAccount(stub shim.ChaincodeStubInterface, args []string) pb.Response { if len(args) != 2 { return shim.Error("Incorrect number of arguments. Expecting 2") } account := args[0] status := args[1] accountAsBytes, err := stub.GetState(account) if err != nil { return shim.Error(err.Error()) } // fmt.Printf("setLock - begin %s \n", string(tokenAsBytes)) accountObj := Account{} json.Unmarshal(accountAsBytes, &accountObj) var statusflag bool if status == "true" { statusflag = true } else { statusflag = false } accountObj.Frozen = statusflag accountAsBytes, err = json.Marshal(accountObj) if err != nil { return shim.Error(err.Error()) } err = stub.PutState(account, accountAsBytes) if err != nil { return shim.Error(err.Error()) } else { fmt.Printf("frozenAccount - end %s \n", string(accountAsBytes)) } msg := &Msg{Data: string(accountAsBytes), Code: 1, Msg: "冻结成功"} rev, _ := json.Marshal(msg) return shim.Success(rev) } |
请发表评论