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 eth_account

Define a web3 connection using Web3.HTTPProvider and RPC endpoint

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

Define 3 diffent wallet from addresses and private keys using Account.from_key_pair

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

Create a transaction with from, to and value fields to transfer.

from: the sender's address, to: target address to receive kaia.

value field means how many kaia you want to send and you can use the Web3.to_peb utils to convert kaia to peb unit.

Use fill_transaction to add rest of the fields of the transaction like gas limit, Nonce, etc. You can print all the fields after this line if you want to see

Sign the transaction with the user1's private key

Sign the signed_tx with the user2 and user3 private keys

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

Recover user1 address with Account.recover_transaction from signed transaction from user3

web3_multisig_value_transfer_sign_recover.py

from web3py_ext import extend
from web3 import Web3
from eth_account import Account
from web3py_ext.transaction.transaction import (
empty_tx,
fill_transaction,
TxType
)
from cytoolz import merge
w3 = Web3(Web3.HTTPProvider('https://klaytn-mainnet.g.allthatnode.com/full/evm'))
def web3_tx_sign_recover_multisig():
user1 = Account.from_key_pair(
'0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e',
'0xa32c30608667d43be2d652bede413f12a649dd1be93440878e7f712d51a6768a'
)
user2 = Account.from_key_pair(
'0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e',
'0x0e4ca6d38096ad99324de0dde108587e5d7c600165ae4cd6c2462c597458c2b8'
)
user3 = Account.from_key_pair(
'0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e',
'0xc9668ccd35fc20587aa37a48838b48ccc13cf14dd74c8999dd6a480212d5f7ac'
)
value_transfer_tx = empty_tx(TxType.VALUE_TRANSFER)
value_transfer_tx = merge(value_transfer_tx, {
'from' : user1.address,
'to' : user1.address,
'value' : Web3.to_peb(10, "klay"),
})
value_transfer_tx = fill_transaction(value_transfer_tx, w3)
signed_tx = Account.sign_transaction(value_transfer_tx, user1.key)
signed_tx = Account.sign_transaction(signed_tx.rawTransaction, user2.key)
signed_tx = Account.sign_transaction(signed_tx.rawTransaction, user3.key)
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)
recovered = w3.klay.recover_from_transaction(signed_tx.rawTransaction.hex(), "latest")
print("\nsender", user1.address, "\nrecovered", recovered)
web3_tx_sign_recover_multisig()

output

❯ py web3_multisig_value_transfer_sign_recover.py
tx hash: 0xe5c4f8b3bd90bf86660eff4f6e4b51dec84e49ac50adcfff7ca983dcfb2db31d receipt: AttributeDict({'blockHash': HexBytes('0x8e0df2104f3f829e06a23808563b07b22c729e04285ebe76aad08f0fecfb4183'), 'blockNumber': 150557795, 'contractAddress': None, 'cumulativeGasUsed': 51000, 'effectiveGasPrice': 25000000000, 'from': '0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E', 'gasUsed': 51000, 'logs': [], 'logsBloom': HexBytes('0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'), 'status': 1, 'to': '0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E', 'transactionHash': HexBytes('0xe5c4f8b3bd90bf86660eff4f6e4b51dec84e49ac50adcfff7ca983dcfb2db31d'), 'transactionIndex': 0, 'type': 0})
sender 0x82C6a8D94993d49cfd0c1D30F0F8Caa65782cc7E
recovered 0x82c6a8d94993d49cfd0c1d30f0f8caa65782cc7e