EOS的测试网络已经具备了上传和运行智能合约的能力,下面我们参照github上的说明一步一步建立一个示例的智能合约。如果你之前已经将eosd进程关掉了,那么请重新启动起来。
创建一个钱包并导入密钥
官网介绍任何智能合约都要与一个账户关联,因此需要先创建一个钱包
cd~/eos/build/programs/eosc/
./eosc wallet create # 执行该条命令会输出一个密码,需要保持下来,该密码是用来解锁钱包的
为了测试,这里讲inita账户的私钥导入。这个账户在genesis.json有定义,这样就会有权限发送API命令。该账户的私钥可以在config.ini文件中找到。
./eosc wallet import 5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3
为currency创建一个账户
先使用以下命令创建两把公私钥对,后续会将这两对密钥分配为owner_key和active_key。
cd~/eos/build/programs/eosc/
./eosc create key#owner_key
./eosc create key#active_key
你会得到类似下面的结果:
➜ eosc git:(master) ./eosc create key # owner_key
Private key: 5KgZRJVN5M1a6LAv78pqH6GsBq2qjDwJtHYTfJXttgeg9R1gF7n
Public key: EOS8j4yqo5xpnhgHcWA2kKPkgjJEg52yfcw9KDZRtXwwrAyRB5LKq
eosc git:(master) ./eosc create key # active_key
Private key: 5JWEfBmhu4xFcAANpEeSNMCyDhevKGuxcqzXPgPk5TjzBVCvU21
Public key: EOS5pGvbapi7tKX6fMCJ39v5jj79BX7gsZcxFw9vzQ7oaURMLubQf
目前仅仅是两个密钥而已,没有跟任何账户关联。注意:这两个密钥要保存下来,后面要用到。
执行以下命令:
./eosc create account inita currency PUBLIC_KEY_1 PUBLIC_KEY_2
其中create account是创建账户命令,inita是授权账户,currency是我们创建的账户,PUBLIC_KEY_1、PUBLIC_KEY_2是我们上面创建的公私钥对的两个公钥。
实际执行的命令是:
➜ eosc git:(master) ./eosc create account inita currency EOS8j4yqo5xpnhgHcWA2kKPkgjJEg52yfcw9KDZRtXwwrAyRB5LKq EOS5pGvbapi7tKX6fMCJ39v5jj79BX7gsZcxFw9vzQ7oaURMLubQf
返回了一个Json字符串
{
"transaction_id": "4f205b2e2486fe7e68155e6aaf8241aa8b3b31b740865830325a5733c8735e4e",
"processed": {
"refBlockNum": 259,
"refBlockPrefix": 3587751908,
"expiration": "2017-09-16T03:10:09",
"scope": [
"eos",
"inita"
],
"signatures": [
"207652512828e83178e168f74268ca9d185838e3aaa3a2e88aabb45cf874bfeed96237ce601b5667c53816cd2cd7689017f10cb138cd960df1cd4eb1e5d007475d"
],
"messages": [{
"code": "eos",
"type": "newaccount",
"authorization": [{
"account": "inita",
"permission": "active"
}
],
"data": {
"creator": "inita",
"name": "currency",
"owner": {
"threshold": 1,
"keys": [{
"key": "EOS8j4yqo5xpnhgHcWA2kKPkgjJEg52yfcw9KDZRtXwwrAyRB5LKq",
"weight": 1
}
],
"accounts": []
},
"active": {
"threshold": 1,
"keys": [{
"key": "EOS5pGvbapi7tKX6fMCJ39v5jj79BX7gsZcxFw9vzQ7oaURMLubQf",
"weight": 1
}
],
"accounts": []
},
"recovery": {
"threshold": 1,
"keys": [],
"accounts": [{
"permission": {
"account": "inita",
"permission": "active"
},
"weight": 1
}
]
},
"deposit": "0.0001 EOS"
},
"hex_data": "000000008040934b00000079b822651d010000000103f96505ab0f65b85208a91a4e7fdb6966772113c0abaf2daa30bc5c68d67c0f320100000100000001027a2085805f5523d91d9902a72fea76f1ffe7e87da5765f9291621f395f957272010000010000000001000000008040934b00000000149be8080100010000000000000004454f5300000000"
}
],
"output": [{
"notify": [],
"deferred_transactions": []
}
]
}
}
使用以下命令检查是否成功
eosc git:(master) ./eosc get account currency
返回
{
"name": "currency",
"eos_balance": "0.0000 EOS",
"staked_balance": "0.0001 EOS",
"unstaking_balance": "0.0000 EOS",
"last_unstaking_time": "2106-02-07T06:28:15",
"permissions": [{
"name": "active",
"parent": "owner",
"required_auth": {
"threshold": 1,
"keys": [{
"key": "EOS5pGvbapi7tKX6fMCJ39v5jj79BX7gsZcxFw9vzQ7oaURMLubQf",
"weight": 1
}
],
"accounts": []
}
},{
"name": "owner",
"parent": "owner",
"required_auth": {
"threshold": 1,
"keys": [{
"key": "EOS8j4yqo5xpnhgHcWA2kKPkgjJEg52yfcw9KDZRtXwwrAyRB5LKq",
"weight": 1
}
],
"accounts": []
}
}
]
}
将active_key导入的钱包,还记得我们产生的两个公私钥对吗?将active_key私钥写到参数里面
./eosc wallet import 5JWEfBmhu4xFcAANpEeSNMCyDhevKGuxcqzXPgPk5TjzBVCvU21
将currency合约上传到区块链
在上传之前先确认一下当前的合约是否已经在区块链上了
./eosc get code currency
如果返回:
code hash: 0000000000000000000000000000000000000000000000000000000000000000
则说明区块链上没有该合约,可以上传。使用命令:
./eosc set contract currency ../../contracts/currency/currency.wast ../../contracts/currency/currency.abi
再次使用命令确认:
./eosc get code currency
可以得到类似下面的返回:
code hash: a1c8c84b4700c09c8edb83522237439e33cf011a4d7ace51075998bd002e04c9
说明合约已经传到区块链上了
使用命令确认currency合约有适当的余额
./eosc get table currency currency account
{"rows": [{"account":"account","balance": 1000000000 } ],"more":false}
使用currency合约转移资金
任何人都可以在任何时间发送任何消息到任何合约上,但是合约可以拒绝那些没有给出任何权限的消息。消息不能被随意发送,而是需要带有权限等级一个或多个账号来发送。下面的命令说明一个“transfer”的消息是如何发送给currency合约的。
我们定义一个消息
'{"from":"currency","to":"inita","amount":50}' #从currency到inita账号,金额是50元
使用以下命令来发送
./eosc push message currency transfer'{"from":"currency","to":"inita","amount":50}'--scope currency,inita --permission currency@active
你将得到类似下面的返回
{
"transaction_id": "aed517ce12e32578b5cb13653bf36a905d1c7d7ba8aed9c456cf1c11cc7037a6",
"processed": {
"refBlockNum": 10598,
"refBlockPrefix": 1100393,
"expiration": "2017-09-24T03:35:39",
"scope": [
"currency",
"inita"
],
"signatures": [
"1f44a17e906ef25ec5bdb829a72b55d28da0523c9a5646faf3b460dacca9744e22014cc0351a0452159fd0c8235346d04eddea25ce97c5702d2955bea1ebbd9e07"
],
"messages": [{
"code": "currency",
"type": "transfer",
"authorization": [{
"account": "currency",
"permission": "active"
}
],
"data": {
"from": "currency",
"to": "inita",
"amount": 50
},
"hex_data": "00000079b822651d000000008040934b3200000000000000"
}
],
"output": [{
"notify": [{
"name": "inita",
"output": {
"notify": [],
"deferred_transactions": []
}
}
],
"deferred_transactions": []
}
]
}
}
假如上述命令,你得到了一个错误的返回
An error occurred while submitting the transaction for this command!
The transaction requires permissions that could not be authorized by the wallet.
Missing authrizations:
- currency@active
Please make sure the proper keys are imported into an unlocked wallet and try again!
需要你打开钱包并解锁,解锁时会让你输入密码,就是我们最初产生钱包时的密码。然后重新执行上面的命令。
./eosc wallet open
./eosc wallet unlock
查询两个账户的余额
./eosc get table inita currency account
{
"rows": [{
"account": "account",
"balance": 50
}
],
"more": false
}
./eosc get table currency currency account
{
"rows": [{
"account": "account",
"balance": 999999950
}
],
"more": false
}
OK,今天就到这里。
网友评论
./eosc push message currency transfer'{"from":"currency","to":"inita","amount":50}'--scope currency,inita --permission currency@active
把amount改成quantity,过了
1112431ms thread-0 main.cpp:941 main ] Failed with error: unspecified (0)
Wallet not found: default
Request Path: localhost:8888/v1/wallet/import_key, Request Post Data: ["default","5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3"]
1687025ms thread-0 main.cpp:941 main ] Failed with error: unknown key (13)
unknown key:
Request Path: localhost:8888/v1/chain/get_required_keys, Request Post Data: {"transaction":{"expiration":"2017-03-30T12:00:30","region":0,"ref_block_num":0,"ref_block_prefix":0,"packed_bandwidth_words":0,"context_free_cpu_bandwidth":0,"context_free_actions":[],"actions":[{"account":"eosio","name":"newaccount","authorization":[{"actor":"inita","permission":"active"}],"data":"000000000093dd740000001e4d75af460100000000010003fc162086601511335e7c0c6fc8cc3a0c1509a55b222c26b63076180705fffab501000100000000010003418fa74d706d106c5fb2f9676bfb300f8f276c303b8232c4e5932934c4ee202301000100000001000000000093dd7400000000a8ed3232010000"}]},"available_keys":[]}
ERROR: ValidationError: wast-file=../../contracts/currency/currency.wast,改了文件路径依然是找不到currency.wast,麻烦可以解答一下吗?
./eosc push message currency transfer'{"from":"currency","to":"inita","amount":50}'--scope currency,inita --permission currency@active
报错信息是
287983ms main.cpp:1099 operator() ] Converting argument to binary...
288014ms main.cpp:1166 main ] Failed with error: Parse Error (4)
Unexpected char '99' in "currency"
现在currency合约有个隐藏bug,比如你用inta向inita转帐,账户余额是会增长的。