此文将投稿给“比原链|用技术书写未来”。
前言:作为一个2016年末开始投资区块链的Python程序员,我对比原链从诞生发布到主网上线的过程是很有记忆的,公司新的业务是比原链挖矿和钱包项目,我开始接触Bytom的代码,这一系列文章将是我学习比原链技术之路,希望能和你一起进步。
在之前我们已经编译运行了比原链节点了,在bytom/目录下,有cmd/目录,cmd/bytomd/是之前我们运行节点使用的,/cmd/bytomcli/ 目录是与节点通信的client工具,使用 netstat -ltn
命令,bytomd运行后开放了9888端口,可以直接通过ip:9888 访问Dashboard,在这之前查看 可以使用bycomcli 命令行工具创建访问所需要的access-token。
但是在程序中远程调试和调用的需要,更多是使用比原链节点的rpc api来代替命令行交互,我使用Python,所以 会使用Python来封装接口。
class btm(object): def __init__(self): self.url = 'http://118.xx.xxx.xx:9888' self.access_token = base64.b64encode(b'mac:xxx00efe24566804138907b6e9') self.authHeader = { 'Authorization': 'Basic ' + self.access_token.decode()} def create_key(self,alias,password): uri = self.url+'/create-key' playload = { 'alias':alias,'password':str(password)} r = requests.post(uri,json=playload,timeout=10,headers=self.authHeader) return json.loads(r.text) def list_keys(self): uri = self.url+'/list-keys' r = requests.post(uri,timeout=10,headers=self.authHeader) return json.loads(r.text)复制代码
这是节点一些rpc功能举例,可以根据需要把所需要的接口封装,其中在远程访问是需要创建的access-token需要经过base64编码并放在Headers中。
比原链最近发布了比原链智能合约语言Equity,可以使用智能合约了,由于之前一章我们搭建节点时,比原链还没有发布智能合约,所以我们需要更新下节点来支持我们智能合约的编译。通过Git下Bytom代码库更新代码再次编译,所有区块文件和钱包文件都在。运行节点后,就已经支持compile接口啦。
学习,感觉学习曲线是比较友好的,我将使用Python编译和部署一个简单的合约。
准备环境:Linux Ubuntu 16.04 Python3.6
1../bytomcli create-key super 111222
创建keystore文件
2../bytomcli create-account alias root_xpub
使用之前key的xpub来创建账户
3../bytomcli list-accounts
找到我们创建账户的id和xpubs,后续要用
4../bytomcli create-asset GOLD xpubs
使用我们之前账户的xpubs创建一种我们自定义的叫GOLD的资产
5../bytomcli list-assets
可以找到我们已经创建的GOLD资产,找到资产id,我们后续要用
6.编写一个基本的智能合约,这个合约表示锁定一些资产,并且只能使用对应pubkey才能解锁资产
contract = ''' contract LockBySuper (pubkey: PublicKey) locks SuperValue { clause spend(sig: Signature) { verify checkTxSig(pubkey,sig) unlock SuperValue } }复制代码
- 构建向节点发送编译的body内容
body = { 'contract':'contract LockWithPublicKey(publicKey: PublicKey) locks locked { clause unlockWithSig(sig: Signature) { verify checkTxSig(publicKey, sig) unlock locked }}', 'args':[ { 'string':'66be3da3ea40f3d37075e32d1b3a4beca03703d27d9ed8c4a8edd047961e0d6d' } ]}复制代码
这里的string类型放置的就是pubickey值,可以用./bytomcli list-key account_id
获取到
8.编译合约
import requestsimport base64node = 'http://118.24.xxx.xx:9888/compile'access_token = base64.b64encode(b'mac:xxxxxfff4bf00ea3d78f00bab81ab57f0c6746117c857d241')authHeader = { 'Authorization': 'Basic '+access_token.decode()}def main(): r = requests.post(url=node,headers=authHeader,json=body) print(r.text)复制代码
执行main()方法后,节点返回编译后的信息
表示编译成功。返回结构中的program值是我们要锁定的合约
9.锁定合约,编译完成后,需要将合约锁定,这里和发送资产一样使用build-transaction方法,编写交易body
{ "base_transaction":null,"actions":[{ "account_id":"0BF63M2UXXXX","amount":20000000,"asset_id":"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff","type":"spend_account"},{ "account_id":"0BF63M2UXXXX","amount":999,"asset_id":"a937476fdb0585b466c312bb4e2b4a157d50dfc6270d53d8acd49d9ce43d3140","type":"spend_account"},{ "amount":999,"asset_id":"a937476fdb0585b466c312bb4e2b4a157d50dfc6270d53d8acd49d9ce43d3140","control_program":"bm1q50u3z8empm5ke0g3ngl2t3sqtr6sd7cepd3z68","type":"control_program"}],"ttl":0,"time_range": 1521625823}复制代码
表示使用这个账户来锁定1000个GOLD资产
def build_transaction(self,account_id,amount,address): uri = self.url+'/build-transaction' r = requests.post(uri,json=playload,headers=self.authHeader) return json.loads(r.text)复制代码
- build-transaction后使用钱包密码,对创建的交易进行签名
def sign_transaction(self,password,builded_transaction): uri = self.url+'/sign-transaction' playload = { 'password':password,'transaction':builded_transaction} r = requests.post(uri,json=playload,headers=self.authHeader) return json.loads(r.text)复制代码
被签名的就是之前返回的json数据
11.向节点提交已被签署的transaction
def submit_transaction(self,raw_transaction): uri = self.url+'/submit-transaction' playload = { 'raw_transaction':raw_transaction} r = requests.post(uri,json=playload,headers=self.authHeader) return json.loads(r.text)复制代码
成功后返回的是交易哈希值,至此,一个合约就锁定完成。