7

When Tezos needs to sign a baking or endorsement operation payload, byte 0 will be a 0x01 for a baking operation or 0x02 for an endorsement operation. Bytes 1-5 in the operation payload contain the chain ID (otherwise known as Network), which can be encoded in base58 using this specification:

let chain_id = "\087\082\000" (* Net(15) *)

The resulting chain ID will be a string like NetXdQprcVkpaWU (the currently active mainnet chain ID as of Feb. 16th, 2019).

How do I convert the 4-byte field in bytes 1-5 into the base58 encoded Net(15) format using Vitalik's pybitcointools module?

I've tried using the script in scripts/b58_prefix.py to determine the appropriate magicbyte to pass to the bitcoin.bin_to_b58check function, but I'm not getting the appropriate result:

$ ./b58_prefix.py Net 4
15 5722583 [87L, 81L, 215L]

Here is my code:

def get_chain_id(self):
    chainid = bytes.fromhex(self.payload[2:10])
    return bitcoin.bin_to_b58check(chainid, magicbyte=5722583)

On zeronet, an endorsement payload looks like this: 023bb717ee882891d7be5b881cefa98946800e3d67b5d01b4237b3618709defb51ec37c3e100000518ae, where 3bb717ee is the chain id, but that converts to Net1BPz7FKbUqsY and it should be NetXSzLHKwSumh7 on zeronet.

3 Answers 3

5

Your magicbyte seems to be wrong. If you take the decimal byte values from the original, convert them to hex, then pad it with a leading zero, you get

>>> struct.unpack('>L', b'\x00\x57\x52\x00')[0]
5722624

This value should produce the expected result:

>>> payload = '023bb717ee882891d7be5b881cefa98946800e3d67b5d01b4237b3618709defb51ec37c3e100000518ae'
>>> mb = struct.unpack('>L', b'\x00\x57\x52\x00')[0]
>>> chainid = bytes.fromhex(payload[2:10])
>>> bitcoin.bin_to_b58check(chainid, magicbyte=mb)
'NetXSzLHKwSumh7'
1
  • 1
    Yeah 5722624 is the right magicbyte: Feb 17, 2019 at 1:59
4

It looks like you are only actually grabbing 2 bytes of data (4 hex chars). I verified this by decoding the result you got, and it only returning two bytes of data for the given magic byte.

Try making the following change:

def get_chain_id(self):
    chainid = bytes.fromhex(self.payload[2:10])
    return bitcoin.bin_to_b58check(chainid, magicbyte=5722583)
1
  • 1
    Thanks, this is part of the problem - I need to grab 8 characters (4 hex bytes), or self.payload[2:10]. On zeronet, an endorsement payload looks like this: 023bb717ee882891d7be5b881cefa98946800e3d67b5d01b4237b3618709defb51ec37c3e100000518ae, where 3bb717ee is the chain id, but that converts to Net1BPz7FKbUqsY and it should be NetXSzLHKwSumh7 on zeronet. I edited the question above a bit. Thanks again for all your help. Feb 17, 2019 at 0:48
2

First of all, many thanks! You've helped me with solving the block signature mystery :) You can use pytezos.encoding package:

from pytezos.encoding import base58_encode

def get_chain_id(self):
    chainid = bytes.fromhex(self.payload[2:10])
    return base58_encode(chain_id, b'Net')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.