Wo sind die Informationen zum TX-Paketerstellungsprotokoll? Bitcoin als Beispiel, Bitcoin Wiki - Protocol Documentation: tx
Gibt es ein Beispiel für die Serialisierung für Python wie diese Antwort auf Wie man einen einfachen Tx einlöst?
Alles, was in Google gefunden wurde, verwendete verschiedene Bibliotheken.
1) Ismael antwortete in den Kommentaren, dass die Informationen im Yellow Paper verfügbar sind
2) Aus dem gelben Papier von Ethereum wissen wir, dass die logische Struktur einer Transaktion wie folgt ist.
-----------------------------
| Nonce | Up to 32 bytes |
-----------------------------
| GasPrice | Up to 32 bytes |
-----------------------------
| GasLimit | Up to 32 bytes |
-----------------------------
| To | 20 bytes addr |
-----------------------------
| Value | Up to 32 bytes |
-----------------------------
| Data | 0 - unlimited |
-----------------------------
| V | 1 (usually) |
-----------------------------
| R | 32 bytes |
-----------------------------
| S | 32 bytes |
-----------------------------
Notiz:
Nehmen Sie zum Beispiel die Transaktion aus diesem Hash:
0x14a298c1eea89f42285948b7d51eeac2876ca7406c9784b9b90dd3591d156d64
Aus:
"0xf86b80850ba43b7400825208947917bc33eea648809c285607579c9919fb864f8f8703baf82d03a0008025a0067940651530790861714b2e8fd8b080361d1ada048189000c07a66848afde46a069b041db7c29dbcc6becf42017ca7ac086b12bd53ec8ee494596f790fb6a0a69"
das sind 109 Byte. Wenn wir die Daten analysieren
f86b length
80 nonce (0: this is the minimum an account can have)
85 0ba43b7400 gas price
82 5208 gas limit (this is fixed for simple payments)
94 7917bc33eea648809c285607579c9919fb864f8f (address, always 20 bytes)
87 03baf82d03a000 (value, in theory this can be shrunken to zero)
80 (data, already zero length)
25 (V, one byte)
a0 067940651530790861714b2e8fd8b080361d1ada048189000c07a66848afde46 (R)
a0 69b041db7c29dbcc6becf42017ca7ac086b12bd53ec8ee494596f790fb6a0a69 (S)
Jetzt werde ich versuchen, die RLP-Bibliothek zu verwenden, um die Struktur auszuwählen.
import rlp
tx_message = list()
# tx_len - f8
tx_nonce = ''
tx_gasPrice = 0x0ba43b7400
tx_gasLimit = 0x5208
tx_to = 0xcce5fd90eabab3d5d35119eed7f2ac5796e3d06c
tx_value = 0x03baf82d03a000
tx_data = 0x00
tx_w = 0x25
tx_r = 0x067940651530790861714b2e8fd8b080361d1ada048189000c07a66848afde46
tx_s = 0x69b041db7c29dbcc6becf42017ca7ac086b12bd53ec8ee494596f790fb6a0a69
tx_message.extend(
(
rlp.encode(tx_nonce),
rlp.encode(tx_gasPrice),
rlp.encode(tx_gasLimit),
rlp.encode(tx_to),
rlp.encode(tx_value),
rlp.encode(tx_data),
rlp.encode(tx_w),
rlp.encode(tx_r),
rlp.encode(tx_s),
)
)
result_b = b''.join(tx_message)
result = result_b.hex()
Ich wollte dem obigen Code zeigen, dass es möglich ist, eine Struktur zu wählen, aber das stimmt noch nicht, weil wir die Größe der Transaktion nicht berücksichtigen und nicht unterschreiben. Jetzt werden wir den Arbeitscode umschreiben.
class Transaction(rlp.Serializable):
fields = [
('nonce', big_endian_int),
('gasprice', big_endian_int),
('startgas', big_endian_int),
('to', Binary.fixed_length(20, allow_empty=True)),
('value', big_endian_int),
('data', binary),
('v', big_endian_int),
('r', big_endian_int),
('s', big_endian_int),
]
_sender = None
def __init__(self, nonce, gasprice, startgas, to, value, data, v=0, r=0, s=0):
# self.data = None
to = normalize_address(to, allow_blank=True)
super(Transaction, self).__init__(nonce, gasprice, startgas, to, value, data, v, r, s)
if gasprice >= TT256 or startgas >= TT256 or value >= TT256 or nonce >= TT256:
logging.error("Values way too high!")
def sign(self, key, network_id=None):
"""
Sign this transaction with a private key.
A potentially already existing signature would be overridden.
"""
if network_id is None:
rawhash = sha3(
rlp.encode(
unsigned_tx_from_tx(self),
UnsignedTransaction
)
)
else:
assert 1 <= network_id < 2 ** 63 - 18
rawhash = sha3(
rlp.encode(
rlp.infer_sedes(self).serialize(self)[:-3] +
[network_id, b'', b'']
)
)
key = normalize_key(key)
v, r, s = ecsign(rawhash, key)
if network_id is not None:
self.v += 8 + network_id * 2
ret = self.copy(v=v,
r=r,
s=s)
ret._sender = privtoaddr(key)
return ret
class UnsignedTransaction(rlp.Serializable):
fields = []
for field, sedes in Transaction._meta.fields:
if field not in "vrs":
fields.append((field, sedes))
def unsigned_tx_from_tx(tx):
return UnsignedTransaction(
nonce=tx.nonce,
gasprice=tx.gasprice,
startgas=tx.startgas,
to=tx.to,
value=tx.value,
data=tx.data,
)
def fetch_url_json_path_int(url, path):
def func():
request = req.Request(url, headers={'User-Agent': 'wallet'})
try:
payload = req.urlopen(request).read()
except Exception as e:
logging.error(f'[fetch_url_json_path_int] {e}')
try:
data = loads(payload)
for component in path.split('/'):
if isinstance(data, dict):
data = data[component]
elif isinstance(data, (list, tuple)):
data = data[int(component)]
return data
except Exception as e:
return data
return func
def get_tx_count(address):
return fetch_url_json_path_int(f'{url_tx_count}{address}', 'result')()
url_tx_count = 'https://api.etherscan.io/api?module=proxy&action=eth_getTransactionCount&address='
private_key = hashlib.sha256('This keyword!!!'.encode()).hexdigest()
nonce = int(get_tx_count('0xcce5fd90eabab3d5d35119eed7f2ac5796e3d06c'), 16)
gasPrice = 28500000000
gasLimit = 21000
to = 0x77f5055E19247E091e0C5bb3483190F9E6E43d3f
value = 0
data = codecs.decode('', 'hex')
transaction = Transaction(
nonce=nonce,
gasprice=gasPrice,
startgas=gasLimit,
to=to,
value=value,
data=data,
).sign(private_key)
print(rlp.encode(transaction))
Funktion senden an:
url_broadcast_transaction = 'https://api.blockcypher.com/v1/eth/main/txs/push'
def broadcast_transaction(message):
timeout_in_second = 10
data = {'tx': message.hex()}
params = {'token': None}
r = requests.post(
url=url_broadcast_transaction,
json=data,
params=params,
verify=True,
timeout=timeout_in_second
)
logging.debug(r.text)
return r.text
Hier sehen Sie die fehlenden Module aus dem Code.
Das wichtigste! gasLimit wird für die Transaktion gleich 21000 sein, aber nicht für den Vertrag. gasPrice müssen diesen Link hierher bekommen. Nach Erhalt des gasPrice muss dieser von GWei in Wei umgerechnet werden
Ismael
Джон Смит
Джон Смит
Ismael
Ernesto Gomez