Created
February 24, 2020 11:07
-
-
Save andelf/d5f8fb18295836e9e264cd41c1575a0c to your computer and use it in GitHub Desktop.
Split Raw transaction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# define P1_FIRST 0x00 | |
# define P1_MORE 0x80 | |
# define P1_LAST 0x90 | |
from google.protobuf.internal.decoder import _DecodeVarint32 | |
from base import parse_bip32_path | |
def decode_varint32(raw, offset): | |
key, pos = _DecodeVarint32(raw, offset) | |
# print(f"! Remain: {len(raw[offset:])}") | |
# print(f"! Varint: fieldNo={key >> 3} type={key & 0x7}, pos={pos}") | |
return key, pos | |
def get_next_length(tx): | |
field, pos = decode_varint32(tx, 0) | |
size, newpos = decode_varint32(tx, pos) | |
if field & 0x07 == 0: | |
return newpos | |
return size + newpos | |
transactionRaw = bytes.fromhex( | |
"0a027d52220889fd90c45b71f24740e0bcb0f2be2c5a67080112630a2d747970" | |
"652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e5472616e7366" | |
"6572436f6e747261637412320a1541c8599111f29c1e1e061265b4af93ea1f27" | |
"4ad78a1215414f560eb4182ca53757f905609e226e96e8e1a80c18c0843d70d0" | |
"f5acf2be2c" | |
) | |
# set_permission | |
transactionRaw = bytes.fromhex( | |
"0a02785e220829557712af17b02140e2ebe3b2872e5ab802082e12b3020a3c747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e4163636f756e745065726d697373696f6e557064617465436f6e747261637412f2010a15411563915e194d8cfba1943570603f7606a3115508123f1a056f776e657220013a190a154119e7e376e7c213b7e7e7e46cc70a5dd086daff2a10013a190a15411563915e194d8cfba1943570603f7606a31155081001224b080210021a06616374697665200132207fff1fc0033e0b000000000000000000000000000000000000000000000000003a190a154119e7e376e7c213b7e7e7e46cc70a5dd086daff2a1001224b080210021a06616374697665200132207fff1fc0033e0b000000000000000000000000000000000000000000000000003a190a15411563915e194d8cfba1943570603f7606a3115508100170a49ce0b2872e" | |
) | |
transactionRaw = bytes.fromhex( | |
"0a024f952208e6530b36b320608940f8ddc8b6872e5aeb01082e12e6010a3c747970652e676f6f676c65617069732e636f6d2f70726f746f636f6c2e4163636f756e745065726d697373696f6e557064617465436f6e747261637412a5010a1541340967e825557559dc46bbf0eabe5ccf99fd134e123f1a056f776e657220013a190a1541340967e825557559dc46bbf0eabe5ccf99fd134e10013a190a15415cbdd86a2fa8dc4bddd8a8f69dba48572eec07fb1001224b080210021a06616374697665200132207fff1fc0033e01000000000000000000000000000000000000000000000000003a190a1541340967e825557559dc46bbf0eabe5ccf99fd134e100170c292c5b6872e" | |
) | |
path = "44'/195'/0'/0/0" | |
donglePath = parse_bip32_path(path) | |
def apduMessage(INS, P1, P2, MESSAGE): | |
hexString = "E0{:02x}{:02x}{:02x}{:02x}{}".format(INS, P1, P2, len(MESSAGE) // 2, MESSAGE) | |
print('send hex:', hexString) | |
def sign(path, tx, signatures=[], verbose=False): | |
max_length = 255 | |
to_send = [] | |
start_bytes = [] | |
data = bytearray.fromhex(f"05{path}") | |
while len(tx) > 0: | |
# get next message field | |
newpos = get_next_length(tx) | |
assert newpos < max_length | |
if (len(data) + newpos) > max_length: | |
# add chunk | |
to_send.append(data.hex()) | |
data = bytearray() | |
continue | |
# append to data | |
data.extend(tx[:newpos]) | |
tx = tx[newpos:] | |
# append last | |
to_send.append(data.hex()) | |
token_pos = len(to_send) | |
to_send.extend(signatures) | |
if len(to_send) == 1: | |
start_bytes.append(0x10) | |
else: | |
start_bytes.append(0x00) | |
for i in range(1, len(to_send) - 1): | |
if i >= token_pos: | |
start_bytes.append(0xA0 | 0x00 | i - token_pos) | |
else: | |
start_bytes.append(0x80) | |
if not (signatures is None) and len(signatures) > 0: | |
start_bytes.append(0xA0 | 0x08 | len(signatures) - 1) | |
else: | |
start_bytes.append(0x90) | |
result = None | |
for i in range(len(to_send)): | |
pack = apduMessage(0x04, start_bytes[i], 0x00, to_send[i]) | |
# result, status = self.exchange(pack, True) | |
# if not (status == 0x9000): | |
# return None, status | |
return result, 0x9000 | |
# send signature if any | |
sign(donglePath, transactionRaw) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment