Skip to main content

Multisig Account Key

AccountKeyWeightedMultiSig is an account key type containing a threshold and WeightedPublicKeys which contains a list consisting of a public key and its weight.

In order for a transaction to be valid for an account associated with AccountKeyWeightedMultiSig, the following conditions should be satisfied: _ The weighted sum of the signed public keys should be larger than the threshold. _ The invalid signature should not be included in the transaction. * The number of signed public keys should be less than the number of weightedPublicKeys.

Import extend from web3py_ext to extend web3 to kaia web3

Import necessary utils from web3 and web3py_ext

Create a Web3 instance with the specified kaia Baobab testnet URL

Also, you can change the provider URL from baobab to allthatnode.

Define 3 different accounts using Account.from_key

Creating an empty transaction of type TxType.ACCOUNT_UPDATE. You can use empty_tx util to get a tx with default fields filled.

Merge additional fields like sender and keys into the empty tx by using the merge util.

In this case, the account keys to update is the mutisig key and each key inside contains a compressed public key and its weight. The compressed_key util will extract the compressed public key from the key

Use fill_transaction to add more params to transaction object like gas limit...

You can use the to_pretty util to print the formatted tx.

Sign the account update tx type. You must sign it with the all 3 loaded accounts

Sending the signed transaction to the network and waiting receipt until it is completely executed in the blockchain

web3_account_update_multisig.py

from web3py_ext import extend
from web3 import Web3
from eth_account import Account
from web3py_ext.klaytn_account.utils import compressed_key
from web3py_ext.klaytn_account.account_key import KeyType
from web3py_ext.transaction.transaction import (
empty_tx,
fill_transaction,
TxType
)
from web3py_ext.utils.klaytn_utils import (
to_pretty,
bytes_to_hex_str
)
from cytoolz import merge
w3 = Web3(Web3.HTTPProvider(
'https://public-en-kairos.node.kaia.io'
))
def web3_account_update_multisig():
user1 = Account.from_key("0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a")
user2 = Account.from_key("0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8")
user3 = Account.from_key("0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac")
account_update_tx = empty_tx(TxType.ACCOUNT_UPDATE)
account_update_tx = merge(account_update_tx, {
'from' : user1.address, #0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e
'key' : {
'type': KeyType.MULTISIG,
'threshold': 2,
'keys': [
{
'weight':1,
'key': compressed_key(user1),
},
{
'weight':1,
'key': compressed_key(user2),
},
{
'weight':1,
'key': compressed_key(user3),
},
]
}
})
account_update_tx = fill_transaction(account_update_tx, w3)
print(to_pretty(account_update_tx))
# sign the kaia specific transaction type with web3py
signed_tx = Account.sign_transaction(account_update_tx, user1.key)
signed_tx = Account.sign_transaction(signed_tx.rawTransaction, user2.key)
signed_tx = Account.sign_transaction(signed_tx.rawTransaction, user3.key)
print('\nrawTransaction:', bytes_to_hex_str(signed_tx.rawTransaction))
tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
tx_receipt = w3.eth.wait_for_transaction_receipt(tx_hash)
print('tx hash: ', tx_hash, 'receipt: ', tx_receipt)
web3_account_update_multisig()

output

❯ py web3_account_update_multisig.py
{
"from": "0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E",
"gas": 159000,
"gasPrice": 50000000000,
"nonce": 103,
"chainId": 1001,
"type": 32,
"key": {
"type": 4,
"threshold": 2,
"keys": [
{
"weight": 1,
"key": "0x021473839f05083617d532325ce8aa40edffb2bc79f1ce17c77cc41f92f027dd82"
},
{
"weight": 1,
"key": "0x03dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cd"
},
{
"weight": 1,
"key": "0x03f26489914098c5da51f0f646e3000da4d6197217df082b4f7ce1530f0a0cbf2a"
}
]
}
}
rawTransaction: 20f9016b67850ba43b740083026d189482c6a8d94993d49cfd0c1d30f0f8caa65782cc7eb87204f86f02f86ce301a1021473839f05083617d532325ce8aa40edffb2bc79f1ce17c77cc41f92f027dd82e301a103dc9dccbd788c00fa98f7f4082f2f714e799bc0c29d63f04d48b54fe6250453cde301a103f26489914098c5da51f0f646e3000da4d6197217df082b4f7ce1530f0a0cbf2af8d5f8458207f6a0978b0c4dcfb9dfd4351842463519f7913a9653bb3954fde04e8c81b59c5f0138a04384e1e3436a43d165f4a03cac64f4a60fbd237d7473f58016bda5381c33a1d2f8458207f6a0431be32222e5dea7d4126254fea9784f9b55171948506477b876995cf04e8185a06d755a79656a7e32f179548e00e314bc37c78d67918b89abc7390083a64c91dcf8458207f5a0c4bc3a38652ede87c9c1f7057b63c9d4ae1bb694d722c36b6901b4ec0b258dbca02559cae1ebcf3baa23a9cbe6fddb81d652f44636534cc9214c26d6127be5b849
tx hash: 0x0774fac9bc9f1b49b4fb4b7a9af87fef52f298e2cbdeb61491eab7bdc401758d receipt: AttributeDict({'blockHash': HexBytes('0xd15a2095f70243121b427aeeebb507937c8bc808526bfa5990806a12df8a3d6f'), 'blockNumber': 150554112, 'contractAddress': None, 'cumulativeGasUsed': 111000, 'effectiveGasPrice': 25000000000, 'from': '0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E', 'gasUsed': 111000, 'logs': [], 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'status': 1, 'to': '0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E', 'transactionHash': HexBytes('0x0774fac9bc9f1b49b4fb4b7a9af87fef52f298e2cbdeb61491eab7bdc401758d'), 'transactionIndex': 0, 'type': 0})