1、创建账户
package main
import (
"fmt"
"github.com/meshplus/gosdk/account"
)
//在window环境下遇到一些运行时错误,但是在linux环境下运行正常
//原因可能是:windows.crypto需要在本地和https生产环境中使用
//参考:https://www.jianshu.com/p/e36c2282e2bf
func main() {
fmt.Println("********* result ************")
fmt.Println()
//创建账号
//把密码设置为“123”,当做参数传进去
//通过账户类型创建账户
ac1, err := account.NewAccountJson(account.ECDES, "123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac1:", ac1)
//创建国密账户
ac2, err := account.NewAccountSm2("123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac2:", ac2)
//创建ed25519类型账户
ac3, err := account.NewAccountED25519("123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac3:", ac3)
//创建ecdsa账户
ac4, err := account.NewAccount("123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac4:", ac4)
//创建R1账户
ac5, err := account.NewAccountR1("123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac5:", ac5)
fmt.Println()
fmt.Println("********* end ************")
}
运行结果:
2、获取账户的key
输入账户json字符串和密码,输出key
密码必须是创建账户的密码,不然报“decrypt private key failed”错误
package main
import (
"fmt"
"github.com/meshplus/gosdk/account"
)
//在window环境下遇到一些运行时错误,但是在linux环境下运行正常
//原因可能是:windows.crypto需要在本地和https生产环境中使用
//参考:https://www.jianshu.com/p/e36c2282e2bf
func main() {
fmt.Println("********* result ************")
fmt.Println()
//创建账号
//把密码设置为“123”,当做参数传进去
//通过账户类型创建账户
ac1, err := account.NewAccountJson(account.ECDES, "123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac1:", ac1)
//获取账户key
key, err := account.GenKeyFromAccountJson(ac1, "123")
if err != nil {
fmt.Println(err)
}
fmt.Println("key:", key)
fmt.Println()
fmt.Println("********* end ************")
}
正确运行结果:
错误运行结果:
3、创建DID账户,并获取key
did账户与普通账户在国密场景一致,仅需要对非国密情况进行区分,由此带来的变化如下
package main
import (
"fmt"
"github.com/meshplus/gosdk/account"
)
//在window环境下遇到一些运行时错误,但是在linux环境下运行正常
//原因可能是:windows.crypto需要在本地和https生产环境中使用
//参考:https://www.jianshu.com/p/e36c2282e2bf
func main() {
fmt.Println("********* result ************")
fmt.Println()
//创建DID账户
//把密码设置为“123”,当做参数传进去
//通过ecdsa创建账户
ac1, err := account.NewAccountDID("123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac1:", ac1)
//通过加密类型创建账户
ac2, err := account.NewDIDAccountJson(account.ECDES, "123")
if err != nil {
fmt.Println(err)
}
fmt.Println("ac2:", ac2)
//通过key生成DID账户
accountJson, _ := account.NewAccountSm2("123")
chainId := "chainId_01"
//生成普通账户key
key, _ := account.GenKeyFromAccountJson(accountJson, "123")
suffix := "didAddr_suffix"
didKey := account.NewDIDAccount(key.(account.Key), chainId, suffix)
fmt.Println("didkey:", didKey)
//通过账户json生成key
key1, err := account.GenDIDKeyFromAccountJson(ac1, "123")
if err != nil {
fmt.Println(err)
}
fmt.Println("key1:", key1)
fmt.Println()
fmt.Println("********* end ************")
}
运行结果:
4、初始化RPC结构体
首先编写配置文件hpc.toml
title = "GoSDK configuratoin file"
namespace = "global"
#发送重新连接请求间隔(/ms)
reConnectTime = 10000
[jsonRPC]
nodes = ["172.16.5.3","172.16.5.3","172.16.5.3","172.16.5.3"]
# JsonRpc connect port
ports = ["8081", "8082", "8083", "8084"]
[webSocket]
# webSocket connect port
ports = ["11001", "11002", "11003", "11004"]
[polling]
#重发次数
resendTime = 10
#第一次轮训时间间隔 unit /ms
firstPollingInterval = 100
#发送一次,第一次轮训的次数
firstPollingTimes = 10
#第二次轮训时间间隔 unit /ms
secondPollingInterval = 1000
#发送一次,第二次轮训的次数
secondPollingTimes = 10
[privacy]
#send Tcert during the request or not
sendTcert = true
#if sendTcert is true , you should add follow path.
#the paths followed are relative to conf root path
sdkcertPath = "certs/sdkcert.cert"
sdkcertPrivPath = "certs/sdkcert.priv"
# sdkcertPath = "certs/sdkcert_cfca.cert"
# sdkcertPrivPath = "certs/sdkcert_cfca.priv"
uniquePubPath = "certs/unique.pub"
uniquePrivPath = "certs/unique.priv"
cfca = false
[security]
#Use Https
https = true
#If https is true, you shoule add follow properties
#the paths followed are relative to conf root path
tlsca = "certs/tls/tlsca.ca"
tlspeerCert = "certs/tls/tls_peer.cert"
tlspeerPriv = "certs/tls/tls_peer.priv"
[log]
#设置日志输出门槛
#"CRITICAL","ERROR","WARNING","NOTICE","INFO","DEBUG",
log_level = "DEBUG"
#存放日志文件夹
log_dir = "../logs"
[transport]
# MaxIdleConns controls the maximum number of idle (keep-alive)
# connections across all hosts. Zero means no limit.
maxIdleConns = 0
# MaxIdleConnsPerHost, if non-zero, controls the maximum idle
# (keep-alive) connections to keep per-host. If zero,
# DefaultMaxIdleConnsPerHost is used.
maxIdleConnsPerHost = 10
说明:
-
namespace为初始化时传入的namespace;
-
jspnRPC模块:nodes表示平台各节点的IP;ports也就是平台发送消息的端口。
-
webSocket模块:ports为事件订阅连接的端口,他们分别对应着node中配置的IP。
-
polling模块:resendTime参数表示重发次数;pollingInterval表示轮训去获取交易的时间间隔(分为第一次和第二次),单位为毫秒;pollingTimes表示发送一次交易的轮训次数(分为第一次和第二次)。
-
privacy模块:sendTcert表示开启Tcert,请配合平台一起使用;sdkcertPath和sdkcertPrivPath表示请求tcert时需要用来签名的公私钥对;uniquePubPath和uniquePrivPath表示请求tcert时所使用的请求体公私钥对;cfca表示开启cfca证书。需要注意证书路径均相对于hpc.toml文件。
-
security模块:https开启后则请求都会使用https来发送,tlsca表示客户端需要验证的服务器ca,tlspeerCert表示服务器需要验证的SDK的ca的公钥,tlspeerPriv则为对应的ca公钥的私钥。
-
log模块:log_level表示输出的日志级别。log_dir表示存放日志的文件夹路径。
注意:
所有配置文件、证书都应放在一个文件夹下,默认配置文件夹名为conf,hpc.toml在配置文件夹下根目录,所有配置为文件路径都应相对于配置文件夹存放,例如我们以默认文件夹名conf为例,则上述配置文件中各文件存放应为:
conf
├── certs
│ ├── sdkcert.cert
│ ├── sdkcert.priv
│ ├── unique.priv
│ └── unique.pub
│ ├── tls
│ │ ├── tls_peer.cert
│ │ ├── tls_peer.priv
│ │ └── tlsca.ca
└── hpc.toml
代码:
package main
import (
"fmt"
"github.com/meshplus/gosdk/account"
"github.com/meshplus/gosdk/rpc"
)
//在window环境下遇到一些运行时错误,但是在linux环境下运行正常
//原因可能是:windows.crypto需要在本地和https生产环境中使用
//参考:https://www.jianshu.com/p/e36c2282e2bf
func main() {
fmt.Println("********* result ************")
fmt.Println()
//初始化RPC结构体(默认路径)
rpcAPI1 := rpc.NewRPC()
fmt.Println(rpcAPI1)
rpcAPI1.Close()
//初始化RPC结构体(带路径)
rpcAPI2 := rpc.NewRPCWithPath("/root/go/src/test/conf")
fmt.Println(rpcAPI2)
rpcAPI2.Close()
//构建绑定节点的RPC结构体
//注意绑定节点编号,从1开始
hrpc := rpc.NewRPCWithPath("/root/go/src/test/conf")
a := []int{1}
proxy, err := hrpc.BindNodes(a...)
fmt.Println(proxy)
proxy.Close()
//创建默认RPC结构体
rpc := rpc.DefaultRPC(rpc.NewNode("10.186.77.122", "8081", "11001"))
fmt.Println(rpc)
rpc.Close()
if err != nil {
fmt.Println(err)
}
fmt.Println()
fmt.Println("********* end ************")
}
运行结果:
5、实例化交易
交易是与hyperchain交互的重要形式,在GoSDK中,交易由Transaction结构体代表。
5.1、普通交易
package main
import (
"fmt"
"github.com/meshplus/gosdk/account"
"github.com/meshplus/gosdk/rpc"
)
//在window环境下遇到一些运行时错误,但是在linux环境下运行正常
//原因可能是:windows.crypto需要在本地和https生产环境中使用
//参考:https://www.jianshu.com/p/e36c2282e2bf
func main() {
fmt.Println("********* result ************")
fmt.Println()
// 随机创建账户,获取account json
accountJSON, sysErr := account.NewAccount("TomKK")
if sysErr != nil {
fmt.Println("syserr:", sysErr)
return
}
fmt.Println(accountJSON)
// 根据account json得到*ecdsa.Key结构体
key, sysErr := account.NewAccountFromAccountJSON(accountJSON, "TomKK")
if sysErr != nil {
fmt.Println("key:", key)
return
}
// 自定义构造
//注意hex函数一定要有
transaction := rpc.NewTransaction(key.GetAddress().Hex()).
To("0xbfa5bd992e3eb123c8b86ebe892099d4e9efb783").
Value(int64(1)).
Extra("存证信息").
Simulate(true)
fmt.Println(transaction)
fmt.Println()
fmt.Println("********* end ************")
}
运行结果:
5.2、部署合约交易
package main
import (
"fmt"
"github.com/meshplus/gosdk/account"
"github.com/meshplus/gosdk/hvm"
"github.com/meshplus/gosdk/rpc"
"github.com/meshplus/gosdk/utils/java"
)
//在window环境下遇到一些运行时错误,但是在linux环境下运行正常
//原因可能是:windows.crypto需要在本地和https生产环境中使用
//参考:https://www.jianshu.com/p/e36c2282e2bf
func main() {
fmt.Println("********* result ************")
fmt.Println()
// 随机创建账户,获取account json
accountJSON, sysErr := account.NewAccount("TomKK")
if sysErr != nil {
fmt.Println("syserr:", sysErr)
return
}
fmt.Println("accountJSON:", accountJSON)
// 根据account json得到*ecdsa.Key结构体
key, sysErr := account.NewAccountFromAccountJSON(accountJSON, "TomKK")
if sysErr != nil {
fmt.Println("key:", key)
return
}
//初始化RPC结构体(带路径)
rpcAPI2 := rpc.NewRPCWithPath("/root/go/src/test/conf")
fmt.Println("rpcAPI2:", rpcAPI2)
defer rpcAPI2.Close()
// cr, err := rpcAPI2.CompileContract("/root/go/src/test/contract/test.sol")
// if err != nil {
// fmt.Println(err)
// return
// }
// fmt.Println(cr)
// //构造函数无参solidity合约部署
// transaction := rpc.NewTransaction(key.GetAddress().Hex()).Deploy(cr.Bin[0])
// fmt.Println(transaction)
// 构造函数无参java合约部署
payload, _ := java.ReadJavaContract("../contract/test.java")
transaction := rpc.NewTransaction(key.GetAddress().Hex()).Deploy(payload)
fmt.Println(transaction)
// 构造函数无参HVM合约部署
payload, sysErr = hvm.ReadJar("../contract/test.jar")
if sysErr != nil {
fmt.Println(sysErr)
return
}
transaction = rpc.NewTransaction(key.GetAddress().Hex()).Deploy(payload).VMType(rpc.HVM)
fmt.Println(transaction)
fmt.Println()
fmt.Println("********* end ************")
}
运行结果: