python智能合约编程 -- 在python中调用Eos API

在上一章的最后,我们运行了程序并进入了python的交互模式。如果经常的要调试代码,就会发现交互模式的巨大好处。因为python是动态语言,在将C/C++代码封装好供python调用后,就可以在这个交互模式下任意的输入代码来调试了。而不用像C/C++代码那样,每次改动下都得重新编译下,特别是C++代码,有时候编译的时候真的缓慢到令人无法忍受。

启动应用程序

我们用下面的命令来启动应用程序

./pyeos/pyeos --debug  -i

这里没有--manual-gen-block参数,这样在调试的时候,每次我们发送ts就不用调用eosapi.produce_block来手动产生块了。

下面介绍Eos的主要的api

eosapi.get_info 获取blockchain信息

info = eosapi.get_info()
info
{
    "head_block_num": 4,
    "last_irreversible_block_num": 0,
    "head_block_id": "00000004ef861f97d22241f96eafbf01700ad038fc03ba72f4390963b5cd048b",
    "head_block_time": "2017-10-11T13:16:24",
    "head_block_producer": "inite",
    "recent_slots": "1111111111111111111111111111111111111111111111111111111111111111",
    "participation_rate": 1.0
}
info.head_block_time
'2017-09-23T15:16:18'
info.head_block_num
18624

wallet.create 创建一个新钱包

psw = wallet.create('mywallet')
psw
'PW5JCWXaGkA15s6th6AWCabHewuGASAtrUJjTWoL1Ybx6sG9QzrSb'

PW5JCWXaGkA15s6th6AWCabHewuGASAtrUJjTWoL1Ybx6sG9QzrSb 为钱包的密码,下次再次启动应用程序要用到钱包时,需要用这个密码对钱包进行解锁。在真实的环境中,这个密码是要被小心保管的。因为如果这个密码丢失或者被盗,那就有可能意味着你将损失你所有的数字资产。

wallet.list_wallets 列出所有创建的钱包

wallet.list_wallets()
['mywallet *']

名称后面*表示钱包已经unlock。默认情况下,钱包文件放在data-dir目录下

wallet.open wallet.unlock 打开钱包 解锁钱包

当要用到私钥用来签名或者发送ts时,就需要先将钱包解锁。

wallet.open('mywallet')
wallet.unlock('mywallet','PW5JCWXaGkA15s6th6AWCabHewuGASAtrUJjTWoL1Ybx6sG9QzrSb')

注意,请把PW5JCWXaGkA15s6th6AWCabHewuGASAtrUJjTWoL1Ybx6sG9QzrSb 换成自己的钱包密码。

wallet.import_key 导入一个新的私钥

首先,让我们导入inita的私钥,inita是一个producer,在测试的时候需要用到inita账号,要不然没法创建其它账号。请参考Setting up a wallet and importing account key 以获取更多的信息。

wallet.import_key('mywallet','5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3')

eosapi.create_key 创建一个新的密码

Eos每个帐户可以拥有有多个key,其中最主要的就是owner key和active key.

先创建一个 owner key.

eosapi.create_key()
{'public': 'EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst', 'private': '5JEcwbckBCdmji5j8ZoMHLEUS8TqQiqBG1DRx1X9DN124GUok9s'}

再创建一个 active key

eosapi.create_key()
{'public': 'EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL', 'private': '5JbDP55GXN7MLcNYKCnJtfKi9aD2HvHAdY7g8m67zFTAFkY1uBB'}

把创建的 owner key导入钱包,注意,参数中指定的是私钥,而不是公钥。

wallet.import_key('mywallet','5JEcwbckBCdmji5j8ZoMHLEUS8TqQiqBG1DRx1X9DN124GUok9s')

把创建的 active key导入钱包

wallet.import_key('mywallet','5JbDP55GXN7MLcNYKCnJtfKi9aD2HvHAdY7g8m67zFTAFkY1uBB')

eosapi.create_account

我们已经创建了owner key 和active key,并且已经将它们导入了钱包,在钱包里我们还导入了inita的私钥,现在可以创建一个新的账户了。下面的key1和key2分别为owner key和active key的公钥。这里我们创建了一个名叫currency的账号。

key1 = 'EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst'
key2 = 'EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL'
r = eosapi.create_account('inita', 'currency',key1,key2)
r

输出如下

{
    "transaction_id": "c1b808dd82ad6f299bf0ceaffce36e3134ed533e055fec83930b9b7108b2f4fc",
    "processed": {
        "refBlockNum": 238,
        "refBlockPrefix": 1273616980,
        "expiration": "2017-10-11T13:29:46",
        "scope": [
            "eos",
            "inita"
        ],
        "signatures": [
            "2053bb4fb2cc9aee1e6aa41a7bc4147c8ee8aaffa0352ac9d002f74aa660051dc404704d73f6443d1f650b935f6aedf22492e17ca2785c4209192cc2effafa5472"
        ],
        "messages": [
            {
                "code": "eos",
                "type": "newaccount",
                "authorization": [
                    {
                        "account": "inita",
                        "permission": "active"
                    }
                ],
                "data": {
                    "creator": "inita",
                    "name": "currency",
                    "owner": {
                        "threshold": 1,
                        "keys": [
                            {
                                "key": "EOS61MgZLN7Frbc2J7giU7JdYjy2TqnfWFjZuLXvpHJoKzWAj7Nst",
                                "weight": 1
                            }
                        ],
                        "accounts": []
                    },
                    "active": {
                        "threshold": 1,
                        "keys": [
                            {
                                "key": "EOS5JuNfuZPATy8oPz9KMZV2asKf9m8fb2bSzftvhW55FKQFakzFL",
                                "weight": 1
                            }
                        ],
                        "accounts": []
                    },
                    "recovery": {
                        "threshold": 1,
                        "keys": [],
                        "accounts": [
                            {
                                "permission": {
                                    "account": "inita",
                                    "permission": "active"
                                },
                                "weight": 1
                            }
                        ]
                    },
                    "deposit": "0.0001 EOS"
                },
                "hex_data": "000000008040934b00000079b822651d010000000102934a4748562795f31685de7b0112c3f4428255d42aa8ea420701c29542ede465010000010000000102376f7109de7a6cf12a8d6c713fa7f4d4df8a9e08ecee47e9001583c7b8fcc975010000010000000001000000008040934b00000000149be8080100010000000000000004454f5300000000"
            }
        ],
        "output": [
            {
                "notify": [],
                "deferred_transactions": []
            }
        ]
    }
}

eosapi.get_transaction 获取ts信息

在上面创建帐户的时候会发送一个ts,它的id为c1b808dd82ad6f299bf0ceaffce36e3134ed533e055fec83930b9b7108b2f4fc,我们可以通过这个id来获取这个已经发送的ts的相关信息。当然,可以把这个id替换成其它ts的id以获取其它ts的信息。

r = eosapi.get_transaction('c1b808dd82ad6f299bf0ceaffce36e3134ed533e055fec83930b9b7108b2f4fc')
r
r.transaction
r.transaction.refBlockNum
r.transaction.messages

eosapi.get_account 获取帐户信息

info = eosapi.get_account('eos')
info
{
    "name": "eos",
    "balance": 690000000000,
    "stakedBalance": 0,
    "unstakingBalance": 0,
    "lastUnstakingTime": "2106-02-07T06:28:15",
    "abi": "{\"types\":[{\"newTypeName\":\"AccountName\",\"type\":\"Name\"},{\"newTypeName\":\"ShareType\",\"type\":\"Int64\"}],\"structs\":[{\"name\":\"transfer\",\"base\":\"\",\"fields\":{\"from\":\"AccountName\",\"to\":\"AccountName\",\"amount\":\"UInt64\",\"memo\":\"String\"}},{\"name\":\"lock\",\"base\":\"\",\"fields\":{\"from\":\"AccountName\",\"to\":\"AccountName\",\"amount\":\"ShareType\"}},{\"name\":\"unlock\",\"base\":\"\",\"fields\":{\"account\":\"AccountName\",\"amount\":\"ShareType\"}},{\"name\":\"claim\",\"base\":\"\",\"fields\":{\"account\":\"AccountName\",\"amount\":\"ShareType\"}},{\"name\":\"okproducer\",\"base\":\"\",\"fields\":{\"voter\":\"AccountName\",\"producer\":\"AccountName\",\"approve\":\"Int8\"}},{\"name\":\"setproducer\",\"base\":\"\",\"fields\":{\"name\":\"AccountName\",\"key\":\"PublicKey\",\"configuration\":\"BlockchainConfiguration\"}},{\"name\":\"setproxy\",\"base\":\"\",\"fields\":{\"stakeholder\":\"AccountName\",\"proxy\":\"AccountName\"}},{\"name\":\"updateauth\",\"base\":\"\",\"fields\":{\"account\":\"AccountName\",\"permission\":\"PermissionName\",\"parent\":\"PermissionName\",\"authority\":\"Authority\"}},{\"name\":\"linkauth\",\"base\":\"\",\"fields\":{\"account\":\"AccountName\",\"code\":\"AccountName\",\"type\":\"FuncName\",\"requirement\":\"PermissionName\"}},{\"name\":\"unlinkauth\",\"base\":\"\",\"fields\":{\"account\":\"AccountName\",\"code\":\"AccountName\",\"type\":\"FuncName\"}},{\"name\":\"deleteauth\",\"base\":\"\",\"fields\":{\"account\":\"AccountName\",\"permission\":\"PermissionName\"}},{\"name\":\"newaccount\",\"base\":\"\",\"fields\":{\"creator\":\"AccountName\",\"name\":\"AccountName\",\"owner\":\"Authority\",\"active\":\"Authority\",\"recovery\":\"Authority\",\"deposit\":\"Asset\"}}],\"actions\":[{\"action\":\"transfer\",\"type\":\"transfer\"},{\"action\":\"lock\",\"type\":\"lock\"},{\"action\":\"unlock\",\"type\":\"unlock\"},{\"action\":\"claim\",\"type\":\"claim\"},{\"action\":\"okproducer\",\"type\":\"okproducer\"},{\"action\":\"setproducer\",\"type\":\"setproducer\"},{\"action\":\"setproxy\",\"type\":\"setproxy\"},{\"action\":\"linkauth\",\"type\":\"linkauth\"},{\"action\":\"unlinkauth\",\"type\":\"unlinkauth\"},{\"action\":\"updateauth\",\"type\":\"updateauth\"},{\"action\":\"deleteauth\",\"type\":\"deleteauth\"},{\"action\":\"newaccount\",\"type\":\"newaccount\"}],\"tables\":[]}"
}
>>> info.balance
690000000000

eosapi.set_contract 设置一个帐户的智能合约

set_contract可以用来设置一个帐户的python智能合约或者wasm智能合约。下面,我们来看下如何设置一个python的智能合约。
你可以在 contracts 目录找到相关的python智能合约的示例代码。
其中的1表示是python智能合约,如果是0则是wasm智能合约。

r = eosapi.set_contract('currency','../../programs/pyeos/contracts/currency/currency.py','../../contracts/currency/currency.abi',1,True)
r
{
    "transaction_id": "0dcc5b427dfe17a4c3a83382877ce15252cde30d7c6e063bc59ac5cbb1c14b6e",
    "processed": {
        "refBlockNum": 505,
        "refBlockPrefix": 1794215310,
        "expiration": "2017-10-11T13:43:07",
        "scope": [
            "currency",
            "eos"
        ],
        "signatures": [
            "1f1dbb315088218d45e1e8b5e63e5b00b45f8be0a36111f83d95088479464661321b102dfcec56e740c0ad5ab5ef6e3fb53c7affc509b65c62fef9c378791bcc5c"
        ],
        "messages": [
            {
                "code": "eos",
                "type": "setcode",
                "authorization": [
                    {
                        "account": "currency",
                        "permission": "active"
                    }
                ],
                "data": "00000079b822651d0100b70a6966205f5f6e616d655f5f203d3d20275f5f6d61696e5f5f273a0a09696d706f727420656f736c69625f64756d6d7920617320656f736c69620a656c73653a0a09696d706f727420656f736c69620a696d706f7274207374727563740a0a636f6465203d20656f736c69622e4e28622763757272656e637927290a7461626c65203d20656f736c69622e4e2862276163636f756e7427290a0a636c617373204163636f756e74286f626a656374293a0a096b6579203d20656f736c69622e4e2862276163636f756e7427290a09646566205f5f696e69745f5f2873656c662c73636f70652c62616c616e63653d30293a0a090973656c662e73636f7065203d2073636f70650a090969662062616c616e6365203d3d20303a0a09090973656c662e6c6f616428290a0909656c73653a0a09090973656c662e62616c616e6365203d2062616c616e63650a09646566206973456d7074792873656c66293a0a090972657475726e2073656c662e62616c616e6365203d3d20300a096465662073746f72652873656c66293a0a0909656f736c69622e73746f72655f7536342873656c662e73636f70652c636f64652c7461626c652c4163636f756e742e6b65792c73656c662e62616c616e6365290a09646566206c6f61642873656c66293a0a090973656c662e62616c616e6365203d20656f736c69622e6c6f61645f7536342873656c662e73636f70652c636f64652c7461626c652c4163636f756e742e6b6579290a0a64656620696e697428293a0a23097072696e74282768656c6c6f2066726f6d20696e697427290a0961203d204163636f756e7428636f6465290a092361766f6964206f76657277726974652062616c616e636520616c7265616479206578697374732e0a09696620612e62616c616e6365203d3d20303a0a0909612e62616c616e6365203d203130303030300a0909612e73746f726528290a0a646566206170706c79286e616d652c74797065293a0a23097072696e74282768656c6c6f2066726f6d20707974686f6e206170706c79272c6e616d652c74797065290a23097072696e7428656f736c69622e6e3273286e616d65292c656f736c69622e6e3273287479706529290a0969662074797065203d3d20656f736c69622e4e2862277472616e7366657227293a0a09096d7367203d20656f736c69622e726561644d65737361676528290a0909726573756c74203d207374727563742e756e7061636b2827515151272c6d7367290a2309097072696e7428726573756c74290a090966726f6d5f203d20726573756c745b305d0a0909746f5f203d20726573756c745b315d0a0909616d6f756e74203d20726573756c745b325d0a09090a0909656f736c69622e7265717569726541757468282066726f6d5f20293b0a0909656f736c69622e726571756972654e6f74696365282066726f6d5f20293b0a0909656f736c69622e726571756972654e6f746963652820746f5f20290a0a090966726f6d5f203d204163636f756e742866726f6d5f290a0909746f5f203d204163636f756e7428746f5f290a090969662066726f6d5f2e62616c616e6365203e3d20616d6f756e743a0a09090966726f6d5f2e62616c616e6365202d3d20616d6f756e740a090909746f5f2e62616c616e6365202b3d20616d6f756e740a09090966726f6d5f2e73746f726528290a090909746f5f2e73746f726528290a0a6966205f5f6e616d655f5f203d3d20275f5f6d61696e5f5f273a0a09696e697428290a096170706c7928656f736c69622e4e286227707974686f6e27292c656f736c69622e4e2862277472616e736665722729290a0a0a0a010b4163636f756e744e616d65044e616d6502087472616e7366657200030466726f6d0b4163636f756e744e616d6502746f0b4163636f756e744e616d6506616d6f756e740655496e743634076163636f756e740002076163636f756e74044e616d650762616c616e63650655496e74363401000000b298e982a4087472616e736665720100000080bafac6080369363401076163636f756e7400076163636f756e74"
            }
        ],
        "output": [
            {
                "notify": [],
                "deferred_transactions": []
            }
        ]
    }
}

r = eosapi.get_account('currency')
r
{
    "name": "currency",
    "balance": 0,
    "stakedBalance": 1,
    "unstakingBalance": 0,
    "lastUnstakingTime": "2106-02-07T06:28:15",
    "abi": "{\"types\":[{\"newTypeName\":\"AccountName\",\"type\":\"Name\"}],\"structs\":[{\"name\":\"transfer\",\"base\":\"\",\"fields\":{\"from\":\"AccountName\",\"to\":\"AccountName\",\"amount\":\"UInt64\"}},{\"name\":\"account\",\"base\":\"\",\"fields\":{\"account\":\"Name\",\"balance\":\"UInt64\"}}],\"actions\":[{\"action\":\"transfer\",\"type\":\"transfer\"}],\"tables\":[{\"table\":\"account\",\"indextype\":\"i64\",\"keynames\":[\"account\"],\"keytype\":[],\"type\":\"account\"}]}"
}
>>> r.balance
0

eosapi.get_table 获取表中的数据

这个函数用于获取表中的数据,所有智能合约的数据都是保存在表中的。表结构在abi文件中指定。下面这个例子获取了currency账号的表结构。

eosapi.get_table('currency','currency','account')
{
    "rows": [
        {
            "account": "account",
            "balance": 100000
        }
    ],
    "more": false
}
>>> r.rows[0].balance
100000

eosapi.push_message 发送一个ts

下面来看下如何利用上面创建的currency账号来进行智能合约的调用。下面这个例子介绍了如何将currency中的token发送给inita。

r = eosapi.push_message('currency','transfer','{"from":"currency","to":"inita","amount":50}',['currency','inita'],{'currency':'active'})
eosapi.get_table('currency','currency','account')
{
    "rows": [
        {
            "account": "account",
            "balance": 99950
        }
    ],
    "more": false
}

用get_table可以查看到结果.

eosapi.get_table('inita','currency','account')
{
    "rows": [
        {
            "account": "account",
            "balance": 50
        }
    ],
    "more": false
}

到这里主要的eos api都已经介绍完了,下一篇将介绍如何去编写一个python的智能合约。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容