Skip to content

Commit 70d1d75

Browse files
Merge pull request #195 from InjectiveLabs/f/add-MsgExecuteContract-support
Add MsgExecuteContract and Example
2 parents 8c1c457 + 211b11c commit 70d1d75

File tree

2 files changed

+90
-0
lines changed

2 files changed

+90
-0
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import asyncio
2+
import logging
3+
4+
from pyinjective.composer import Composer as ProtoMsgComposer
5+
from pyinjective.async_client import AsyncClient
6+
from pyinjective.transaction import Transaction
7+
from pyinjective.constant import Network
8+
from pyinjective.wallet import PrivateKey
9+
10+
11+
async def main() -> None:
12+
# select network: local, testnet, mainnet
13+
network = Network.testnet()
14+
composer = ProtoMsgComposer(network=network.string())
15+
16+
# initialize grpc client
17+
# set custom cookie location (optional) - defaults to current dir
18+
client = AsyncClient(network, insecure=False)
19+
await client.sync_timeout_height()
20+
21+
# load account
22+
priv_key = PrivateKey.from_hex("f9db9bf330e23cb7839039e944adef6e9df447b90b503d5b4464c90bea9022f3")
23+
pub_key = priv_key.to_public_key()
24+
address = pub_key.to_address()
25+
account = await client.get_account(address.to_acc_bech32())
26+
27+
# prepare tx msg
28+
# NOTE: COIN MUST BE SORTED IN ALPHABETICAL ORDER BY DENOMS
29+
funds = [
30+
composer.Coin(amount=69, denom='factory/inj1hdvy6tl89llqy3ze8lv6mz5qh66sx9enn0jxg6/inj12ngevx045zpvacus9s6anr258gkwpmthnz80e9'),
31+
composer.Coin(amount=420, denom='peggy0x44C21afAaF20c270EBbF5914Cfc3b5022173FEB7'),
32+
composer.Coin(amount=1, denom='peggy0x87aB3B4C8661e07D6372361211B96ed4Dc36B1B5'),
33+
]
34+
msg = composer.MsgExecuteContract(
35+
sender=address.to_acc_bech32(),
36+
contract="inj1ady3s7whq30l4fx8sj3x6muv5mx4dfdlcpv8n7",
37+
msg='{"increment":{}}',
38+
funds=funds
39+
)
40+
41+
# build sim tx
42+
tx = (
43+
Transaction()
44+
.with_messages(msg)
45+
.with_sequence(client.get_sequence())
46+
.with_account_num(client.get_number())
47+
.with_chain_id(network.chain_id)
48+
)
49+
sim_sign_doc = tx.get_sign_doc(pub_key)
50+
sim_sig = priv_key.sign(sim_sign_doc.SerializeToString())
51+
sim_tx_raw_bytes = tx.get_tx_data(sim_sig, pub_key)
52+
53+
# simulate tx
54+
(sim_res, success) = await client.simulate_tx(sim_tx_raw_bytes)
55+
if not success:
56+
print(sim_res)
57+
return
58+
59+
# build tx
60+
gas_price = 500000000
61+
gas_limit = sim_res.gas_info.gas_used + 20000 # add 20k for gas, fee computation
62+
gas_fee = '{:.18f}'.format((gas_price * gas_limit) / pow(10, 18)).rstrip('0')
63+
fee = [composer.Coin(
64+
amount=gas_price * gas_limit,
65+
denom=network.fee_denom,
66+
)]
67+
tx = tx.with_gas(gas_limit).with_fee(fee).with_memo('').with_timeout_height(client.timeout_height)
68+
sign_doc = tx.get_sign_doc(pub_key)
69+
sig = priv_key.sign(sign_doc.SerializeToString())
70+
tx_raw_bytes = tx.get_tx_data(sig, pub_key)
71+
72+
# broadcast tx: send_tx_async_mode, send_tx_sync_mode, send_tx_block_mode
73+
res = await client.send_tx_sync_mode(tx_raw_bytes)
74+
print(res)
75+
print("gas wanted: {}".format(gas_limit))
76+
print("gas fee: {} INJ".format(gas_fee))
77+
78+
if __name__ == "__main__":
79+
logging.basicConfig(level=logging.INFO)
80+
asyncio.get_event_loop().run_until_complete(main())

pyinjective/composer.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929

3030
from pyinjective.proto.cosmos.base.v1beta1 import coin_pb2 as cosmos_dot_base_dot_v1beta1_dot_coin__pb2
3131

32+
from .proto.cosmwasm.wasm.v1 import tx_pb2 as wasm_tx_pb
33+
3234
from .constant import Denom
3335
from .utils import *
3436
from typing import List
@@ -262,6 +264,14 @@ def MsgSend(self, from_address: str, to_address: str, amount: float, denom: str)
262264
amount=[self.Coin(amount=be_amount, denom=peggy_denom)],
263265
)
264266

267+
def MsgExecuteContract(self, sender: str, contract: str, msg: str, **kwargs):
268+
return wasm_tx_pb.MsgExecuteContract(
269+
sender=sender,
270+
contract=contract,
271+
msg=bytes(msg, "utf-8"),
272+
funds=kwargs.get('funds') # funds is a list of cosmos_dot_base_dot_v1beta1_dot_coin__pb2.Coin. The coins in the list must be sorted in alphabetical order by denoms.
273+
)
274+
265275
def MsgDeposit(self, sender: str, subaccount_id: str, amount: float, denom: str):
266276
peggy_denom, decimals = Denom.load_peggy_denom(self.network, denom)
267277
be_amount = amount_to_backend(amount, decimals)

0 commit comments

Comments
 (0)