基于星云链的智能合约与Dapp(三)——在星云链上发送交易

论坛 期权论坛 区块链     
古川不爱笑   2018-11-20 23:29   3633   0
            Nebulas提供给了我们三种方式去发送交易:
签名 & 发送
密码 & 发送
解锁 & 发送
下面我们分别介绍如何通过以上三种方式在nebulas中发送一笔交易,并验证交易是否成功。
准备账户在星云链上,每个地址表示一个唯一的账户。
在发送交易前,我们需要准备两个账户:一个账户用来发送代币 (称为"from") 和另一个账户来接受代币 (称为"to")。
发送者账户(from)在这里,我们将会使用配置文件
  1. conf/default/genesis.conf
复制代码
中预分配过代币的账户中选择一个作为发送者账户,默认选择
  1. n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE
复制代码

接受者账户(to)我们先创建一个全新的账户来作为接受者,一定不要忘记自己的密码
  1. cd $GOPATH/src/github.com/nebulasio/go-nebulas/./neb account newYour new account is locked with a passphrase. Please give a passphrase. Do not forget this passphrase.Passphrase: Repeat passphrase: Address: n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6
复制代码
提示:你创建的新账户和上面的不一样,请以创建的账户做为接受者继续接下来的实验。
新账户的keystore文件将会被放置在
  1. $GOPATH/src/github.com/nebulasio/go-nebulas/keydir/
复制代码
内。
启动私有链具体的操作这里就不在重复,上篇文章运行星云链已经讲过。
补充:
多久会产生一个新的区块?在星云链上, 在贡献度证明(Proof-of-Devotion, 技术白皮书中有详细描述)被充分验证前,DPoS被选择作为一个过渡方案。DPoS共识算法中,总共有21个矿工,每个矿工会轮流每15s出一个新区块。
在目前的测试环境中,由于我们只启动了21个矿工中的一个,所以需要等待15*21s才会出一个新区块。
一旦一个新区块被挖出,挖块奖励将会被自动发送到当前矿工配置的Coinbase账户中,在conf/example/miner.conf里,该账户就是n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE.
星云链交互星云链提供给开发者HTTP API, RPC API和CLI来和运行中的星云节点交互。我们将会基于HTTP API(API Module| Admin Module)来介绍三种发送交易的方法。
提示:星云链的HTTP服务默认端口号为8685。
首先,在发送新交易前,我们检查下发送者账户的状态。
检查账户状态每个交易如果需要上链,都需要给矿工缴纳一部分手续费,所以发送者账户中需要有一部分钱才能成功发送交易。一般一个普通转账交易,手续费在0.000000002NAS左右,非常少。
我们可以通过API Module中的
  1. /v1/user/accountstate
复制代码
接口来获取发送者账户
  1. n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE
复制代码
的账户信息,检查下是否有足够的钱支付上链手续费。
  1. curl -i -H Accept:application/json -X POST http://localhost:8685/v1/user/accountstate -d '{"address":"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 12:08:55 GMTContent-Length: 74{    "result": {        "balance": "5000023999997020942000000",        "nonce": "137",        "type": 87    }}
复制代码
提示:
Type用于标记账户类型。88表示该账户为智能合约账户,部署一个合约之后,就可以得到一个合约账户。87表示非合约账户,我们通过./neb account new创建的账户就是非合约账户,用户存储链上资产。
Nonce用于标记账户发起的所有交易的顺序。同一个账户,每发起一个新的交易,Nonce就加一,初始为0,第一个交易的Nonce为1。
发送者账户在预分配后拥有5000000000000000000000000(5 * 10^24 )个代币,我的账户用来挖过矿所以大于这个值,1个NAS是1000000000000000000(10^18)个代币,用于支付交易上链的手续费绰绰有余。
然后我们检查接受者账户的状态。
  1. curl -i -H Accept:application/json -X POST http://localhost:8685/v1/user/accountstate -d '{"address":"n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 12:16:32 GMTContent-Length: 48{    "result": {        "balance": "0",        "nonce": "0",        "type": 87    }}
复制代码
正如我们所期望的那样,新账户没有任何代币。
发送交易接下来,我们将介绍星云链上三种发送交易的方式。
签名 & 发送
使用这种方式,我们可以在离线环境下先使用私钥签名好交易,然后把签好名的交易在联网的机器上发出。这是最安全的发送交易的方式,私钥可以完全离线保存,不触网。Web-Wallet正是基于Neb.js采用这种方法发送的交易。
首先,使用Admin Module中的
  1. v1/admin/sign
复制代码
接口给准备发的交易签名,得到交易的二进制数据。
  1. curl -i -H 'Content-Type: application/json' -X POST http://localhost:8685/v1/admin/sign -d '{"transaction":{"from":"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE","to":"n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6", "value":"1000000000000000000","nonce":138,"gasPrice":"1000000","gasLimit":"2000000"}, "passphrase":"passphrase"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 12:40:32 GMTContent-Length: 334{    "result": {        "data": "CiBcDjDaY+cMGizr5zh46o4juL+PWo6MvebNBGwMY64cPhIaGVcH+WT/SVMkY18ix7SG4F1+Z8evXJoA35caGhlXzNurq54Vowfvg0i/Tfqnb5rMh5/ZVOwtIhAAAAAAAAAAAA3gtrOnZAAAKIoBMP2n+NkFOggKBmJpbmFyeUBkShAAAAAAAAAAAAAAAAAAD0JAUhAAAAAAAAAAAAAAAAAAHoSAWAFiQVmw6c4pt2i/FYJXNzW5YR3AqskwScR4WemxaEhmFUdET8VBMfMRMlFuT+C/ieUefWtJ84oRNSI63nFJbrc02aUB"    }}
复制代码
提示:在发送交易时,对于同一个账户,只有当他
  1. Nonce
复制代码
为N的交易上链后,
  1. Nonce
复制代码
为N+1的交易才能上链,有严格的顺序,
  1. Nonce
复制代码
必须严格加1。可以通过GetAccountState接口查看最新的Nonce。如果Nonce没有严格加1,就会报如下的错误:
  1. {"error":"transaction's nonce is invalid, should bigger than the from's nonce"}
复制代码
然后,我们将签好名的交易原始数据提交到本地私有链里的星云节点。
  1. curl -i -H 'Content-Type: applicatioT http://localhost:8685/v1/user/rawtransaction -d '{"data":"CiBcDjDaY+cMGizr5zh46o4juL+PWo6MvebNBGwMY64cPhIaGVcH+WT/SVMkY18ix7SG4F1+Z8evXJoA35caGhlXzNurq54Vowfvg0i/Tfqnb5rMh5/ZVOwtIhAAAAAAAAAAAA3gtrOnZAAAKIoBMP2n+NkFOggKBmJpbmFyeUBkShAAAAAAAAAAAAAAAAAAD0JAUhAAAAAAAAAAAAAAAAAAHoSAWAFiQVmw6c4pt2i/FYJXNzW5YR3AqskwScR4WemxaEhmFUdET8VBMfMRMlFuT+C/ieUefWtJ84oRNSI63nFJbrc02aUB"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 12:50:35 GMTContent-Length: 110{    "result": {        "txhash": "5c0e30da63e70c1a2cebe73878ea8e23b8bf8f5a8e8cbde6cd046c0c63ae1c3e",        "contract_address": ""    }}
复制代码
密码 & 发送
如果你信任一个星云节点帮你保存keystore文件,你可以使用第二种方法发送交易。
首先,上传你的keystore文件到你信任的星云节点的keydir文件夹下。如果在节点在本地,可以使用如下指令。
  1. cp /path/to/keystore.json  /path/to/keydir/
复制代码
然后,我们发送交易的同时,带上我们keystore的密码,在被信任的节点使用SendTransactionWithPassphrase接口上一次性完成签名和发送过程。
  1. curl -i -H 'Content-Type: application/json' -X POST http://localhost:8685/v1/admin/transactionWithPassphrase -d '{"transaction":{"from":"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE","to":"n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6", "value":"1000000000000000000","nonce":139,"gasPrice":"1000000","gasLimit":"2000000"},"passphrase":"passphrase"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 13:22:42 GMTContent-Length: 110{    "result": {        "txhash": "b2e82f7704dc91eeefc2226abd2324c767d5ccbda571636cd4078d4a9b37b15e",        "contract_address": ""    }}
复制代码
提示:因为我们在之前使用
  1. n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE
复制代码
发送了一个
  1. Nonce
复制代码
为1的交易,所以这里新的交易的
  1. Nonce
复制代码
应该增加1,再提交。
解锁 & 发送
这是最危险的发送交易的方法。除非你完全信任一个星云节点,否则不要使用这种方法来发送交易。
首先,上传你的keystore文件到你信任的星云节点的keydir文件夹下。如果在节点在本地,可以使用如下指令。
  1. cp /path/to/keystore.json /path/to/keydir/
复制代码
然后,使用你的keystore文件的密码,在指定的时间范围来在被信任的节点上使用Unlock接口解锁账户。时间单位为纳秒,300000000000为300s。
  1. curl -i -H 'Content-Type: application/json' -X POST http://localhost:8685/v1/admin/account/unlock -d '{"address":"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE","passphrase":"passphrase","duration":"300000000000"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 13:26:04 GMTContent-Length: 26{    "result": {        "result": true    }}
复制代码
一旦一个账户在节点上被解锁,任何可以访问该机器SendTransaction接口的人,都可以直接使用该账户的身份发送交易。
  1. curl -i -H 'Content-Type: application/json' -X POST http://localhost:8685/v1/admin/transaction -d '{"from":"n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE","to":"n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6", "value":"1000000000000000000","nonce":140,"gasPrice":"1000000","gasLimit":"2000000"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 13:27:30 GMTContent-Length: 110{    "result": {        "txhash": "834203293020737fb39a2ba82c07c4de5cfb4b0fece25c53773800a3b59dc74d",        "contract_address": ""    }}
复制代码
交易收据不论使用的哪一种方法发送交易,我们都会得到两个返回值,
  1. txhash
复制代码
  1. contract_address
复制代码
。其中
  1. txhash
复制代码
为交易hash,是一个交易的唯一标识。如果当前交易是一个部署合约的交易,
  1. contract_address
复制代码
将会是合约地址,调用合约时都会使用这个地址,是合约的唯一标识。
使用
  1. txhash
复制代码
我们可以查看交易收据,知道当前交易的状态。
  1. curl -i -H Accept:application/json -X POST http://localhost:8685/v1/user/getTransactionReceipt -d '{"hash":"834203293020737fb39a2ba82c07c4de5cfb4b0fece25c53773800a3b59dc74d"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 13:30:42 GMTContent-Length: 420{    "result": {        "hash": "834203293020737fb39a2ba82c07c4de5cfb4b0fece25c53773800a3b59dc74d",        "chainId": 100,        "from": "n1FF1nz6tarkDVwWQkMnnwFPuPKUaQTdptE",        "to": "n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6",        "value": "1000000000000000000",        "nonce": "140",        "timestamp": "1530797250",        "type": "binary",        "data": null,        "gas_price": "1000000",        "gas_limit": "2000000",        "contract_address": "",        "status": 1,        "gas_used": "20000",        "execute_error": "",        "execute_result": ""    }}
复制代码
这里的status可能有三种状态值:0,1和2。
0: 交易失败. 表示当前交易已经上链,但是执行失败了。可能是因为部署合约或者调用合约参数错误。
1: 交易成功. 表示当前交易已经上链,而且执行成功了。
2: 交易待定. 表示当前交易还没有上链。可能是因为当前交易还没有被打包;如果长时间处于当前状态,可能是因为当前交易的发送者账户的余额不够支付上链手续费。
查询接受者账户余额我们复查一下接受者账户上的钱是否已经到账了。
  1. curl -i -H Accept:application/json -X POST http://localhost:8685/v1/user/accountstate -d '{"address":"n1ZC3JXAQ7eLt7yXCX61n8AWWJLyztuGRh6"}'HTTP/1.1 200 OKContent-Type: application/jsonVary: OriginDate: Thu, 05 Jul 2018 13:32:30 GMTContent-Length: 66{    "result": {        "balance": "3000000000000000000",        "nonce": "0",        "type": 87    }}
复制代码
我们用三种方式分别发送了一笔转账,每笔转一个NAS,所以这里看到接受者账户中已经有了3个NAS,即3000000000000000000个代币。
下一章编写并运行智能合约         
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:50
帖子:9
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP