OSDN Git Service

def5acd6199d2d3efc91b9603e2e8037c9477b7b
[bytom/bytom-kit.git] / app / model / transaction.py
1 import requests
2 import json
3 from app.model import receiver
4
5 # submit_transaction broadcast raw transaction
6 # raw_transaction_str is signed transaction,
7 # network_str is mainnet or testnet
8 # test data 1:
9 #   raw_transaction_str: 070100010160015e0873eddd68c4ba07c9410984799928288ae771bdccc6d974e72c95727813461fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8094ebdc030101160014052620b86a6d5e07311d5019dffa3864ccc8a6bd630240312a052f36efb9826aa1021ec91bc6f125dd07f9c4bff87014612069527e15246518806b654d57fff8b6fe91866a19d5a2fb63a5894335fce92a7b4a7fcd340720e87ca3acdebdcad9a1d0f2caecf8ce0dbfc73d060807a210c6f225488347961402013dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8082eee0020116001418028ef4f8b8c278907864a1977a5ee6707b2a6b00013cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80b8b872011600142935e4869d0317d9701c80a02ecf888143cb9dd200
10 #   network_str: testnet
11 def submit_transaction(raw_transaction_str, network_str):
12     raw_transaction_dict = {
13         "transaction": raw_transaction_str
14     }
15     raw_transaction_json = json.dumps(raw_transaction_dict)
16     headers = {
17         "content-type": "application/json",
18         "accept": "application/json"
19     }
20     if network_str == "mainnet":
21         url = "https://blockmeta.com/api/v2/broadcast-transaction"
22     else:
23         url = "https://blockmeta.com/api/wisdom/broadcast-transaction"
24     response = requests.post(url, headers=headers, data=raw_transaction_json)
25     return {
26         "response": response.text[:-1]
27     }
28
29
30 def decode_raw_transaction(raw_transaction_str):
31     raw_transaction_dict = {
32         "raw_transaction": raw_transaction_str
33     }
34     raw_transaction_json = json.dumps(raw_transaction_dict)
35     headers = {
36         "content-type": "application/json",
37         "accept": "application/json"
38     }
39     url = 'http://127.0.0.1:9888/decode-raw-transaction'
40     response = requests.post(url, headers=headers, data=raw_transaction_json)
41     return {
42         "response": response.text[:-1]
43     }
44
45
46 def get_uvarint(uvarint_str):
47     uvarint_bytes = bytes.fromhex(uvarint_str)
48     x, s, i = 0, 0, 0
49     while True:
50         b = uvarint_bytes[i]
51         if b < 0x80:
52             if i > 9 or i == 9 and b > 1:
53                 return "overflow"
54             return x | int(b) << s, i + 1
55         x |= int(b & 0x7f) << s
56         s += 7
57         i += 1
58
59
60 def decode_raw_tx(raw_tx_str, network_str):
61     tx_input = {
62         "address": "",
63         "amount": 0,
64         "asset_definition": {},
65         "asset_id": "",
66         "control_program": "",
67         "input_id": "",
68         "spend_output_id": "",
69         "type": "",
70         "witness_arguments": []
71     }
72     tx_output = {
73         "address": "",
74         "amount": 0,
75         "asset_definition": {},
76         "asset_id": "",
77         "control_program": "",
78         "id": "",
79         "position": 0,
80         "type": ""
81     }
82     tx = {
83         "fee": 0,
84         "inputs": [],
85         "outputs": [],
86         "size": 0,
87         "time_range": 0,
88         "tx_id": "",
89         "version": 0
90     }
91     tx['size'] = len(raw_tx_str) // 2
92     length = 0
93     offset = 2
94     tx['version'], length = get_uvarint(raw_tx_str[offset:offset+16])
95     offset = offset + 2 * length
96     tx['time_range'], length = get_uvarint(raw_tx_str[offset:offset+16])
97     offset = offset + 2 * length
98     tx_input_amount, length = get_uvarint(raw_tx_str[offset:offset+8])
99     offset = offset + 2 * length
100     for _ in range(tx_input_amount):
101         _, length = get_uvarint(raw_tx_str[offset:offset+16])
102         offset = offset + 2 * length
103         _, length = get_uvarint(raw_tx_str[offset:offset+16])
104         offset = offset + 2 * length
105         input_type = int(raw_tx_str[offset:offset+2], 16)
106         offset += 2
107         if input_type == 0:
108             pass
109         elif input_type == 1:
110             tx_input['type'] = "spend"
111             _, length = get_uvarint(raw_tx_str[offset:offset+16])
112             offset = offset + 2 * length
113             source_id = raw_tx_str[offset:offset+64]
114             offset += 64
115             tx_input['asset_id'] = raw_tx_str[offset:offset+64]
116             offset += 64
117             tx_input['amount'], length = get_uvarint(raw_tx_str[offset:offset+16])
118             offset = offset + 2 * length
119             _, length = get_uvarint(raw_tx_str[offset:offset+16])
120             offset = offset + 2 * length
121             _, length = get_uvarint(raw_tx_str[offset:offset+16])
122             offset = offset + 2 * length
123             control_program_length, length = get_uvarint(raw_tx_str[offset:offset+16])
124             offset = offset + 2 * length
125             tx_input['control_program'] = raw_tx_str[offset:offset+2*control_program_length]
126             offset = offset + 2 * control_program_length
127             tx_input['address'] = receiver.create_address(tx_input['control_program'], network_str)['address']
128             _, length = get_uvarint(raw_tx_str[offset:offset+16])
129             offset = offset + 2 * length
130             witness_arguments_amount, length = get_uvarint(raw_tx_str[offset:offset+16])
131             offset = offset + 2 * length
132             for _ in range(witness_arguments_amount):
133                 argument_length, length = get_uvarint(raw_tx_str[offset:offset+16])
134                 offset = offset + 2 * length
135                 argument = raw_tx_str[offset:offset+2*argument_length]
136                 offset = offset + 2 * argument_length
137                 tx_input['witness_arguments'].append(argument)
138             tx['inputs'].append(tx_input)
139         elif input_type == 2:
140             pass
141     return tx