Erstellen und signieren Sie OFFLINE-Rohtransaktionen?

Ich möchte eine Rohtransaktion erstellen, signieren und mit der eth.sendRawTransactionRPC-Methode übertragen.

Ich möchte dies offline mit Code oder einer Open-Source-Bibliothek ODER online tun, aber ohne die Notwendigkeit, eine bestimmte Brieftasche oder Software zu verwenden.

Es gibt weder eine RPC-Methode zum Erstellen/Signieren der Rohtransaktion, noch kann ich dafür (offline) Bibliotheken finden.

Für jede Hilfe oder Anleitung, wie dies erreicht werden könnte, wäre ich sehr dankbar. Wenn es eine Python-Implementierung gäbe, wäre das großartig.

Die Frage mag anders sein, aber die Antworten sind ähnlich / gleich. Ich verlinke dies hier für zukünftige Referenz. So senden Sie aus einer Cold Wallet: ethereum.stackexchange.com/questions/1019/…

Antworten (6)

ethereumjs-tx ist eine Bibliothek mit diesem Beispiel:

npm install ethereumjs-tx

const Tx = require('ethereumjs-tx').Transaction
var privateKey = new Buffer('e331b6d69882b4cb4ea581d88e0b604039a3de5967688d3dcffdd2270c0fd109', 'hex')

var rawTx = {
  nonce: '0x00',
  gasPrice: '0x09184e72a000', 
  gasLimit: '0x2710',
  to: '0x0000000000000000000000000000000000000000', 
  value: '0x00', 
  data: '0x7f7465737432000000000000000000000000000000000000000000000000000000600057'
}

var tx = new Tx(rawTx)
tx.sign(privateKey)

var serializedTx = tx.serialize()
console.log(serializedTx.toString('hex'))
ethereumjs-tx ist in der Tat großartig. Sie können sich auch dieses Tool ansehen, das ich als GUI-Beispiel für die Verwendung zum Signieren von Transaktionen auf einem Offline-Computer erstellt habe: github.com/kobigurk/frozeth
@kobigurk FYI, wenn Sie ethereumjs-utils für die Generierung privater/öffentlicher Schlüssel verwenden, müssen Sie diese Bibliothek so schnell wie möglich aktualisieren. Es gab einen bösen Füllfehler, der dazu führte, dass gelegentlich der falsche öffentliche Schlüssel aus dem privaten Schlüssel abgeleitet wurde.
@eth Kennen Sie Python-Bibliotheken, um dies zu tun?
Es gibt github.com/ethereum/pyethereum/blob/develop/ethereum/… aber ich habe derzeit keine Beispiele; Ich kann die Antwort bearbeiten, wenn ich etwas finde.
Gibt es eine C#-Version des Offline-Unterzeichners?
@Denis Ich weiß es nicht, aber ich würde mit github.com/Nethereum/Nethereum beginnen und sie dann gemäß ihrer Readme weiter fragen.
Kann ich diesen Code auf einer Web-Client-Seite ausführen? Oder sollte ich reinen JS-Code verwenden?
@eth wie kann ich diesen code in json rpc verwenden.
@YogeshKarodiya Nehmen Sie, was der Code ausgibt, und es sind die Daten dafürsendRawTransaction
@eth Ich verwende json rpc + curl, bitte beziehen Sie sich auf diese Frage ethereum.stackexchange.com/questions/29904/…
Korrekter Import in Version 2.1.2:const Tx = require('ethereumjs-tx').Transaction
@KirillBulgakov Danke, auch die Antwort auf Ihren Kommentar aktualisiert.

In Go würde das Erstellen einer signierten Transaktion etwa so aussehen:

transaction := types.NewTransaction(nonce, recipient, value, gasLimit, gasPrice, input)
signature, _ := crypto.Sign(transaction.SigHash().Bytes(), key)
signed, _ := tx.WithSignature(signature)

wobei der Schlüssel eine Ebene ist *ecdsa.PrivateKey. Wenn Sie mit Ethereum verschlüsselte Konten verwenden möchten, können Sie sich den AccountManager ansehen, der all die ausgefallenen Krypto-Sachen für Sie erledigt, und Sie können einfach eine SignMethode mit einer Eingabetransaktion aufrufen, um sie zu signieren.

Nachdem Sie es signiert haben, müssen Sie es noch über RPC im Netzwerk ankündigen. Das ist bereits für die nativen DApp-Bindungen hier implementiert: https://github.com/ethereum/go-ethereum/blob/develop/accounts/abi/bind/backends/remote.go#L202 , die Sie kopieren, einfügen oder alternativ warten können Bit, bis Felix seinen RPC Go-Client beendet hat.

verwendest du irgendeine Bibliothek? Können Sie den Link zu dieser Bibliothek teilen? Wissen Sie, ob es eine Python-Implementierung gibt?
Dies ist die Go-Ethereum-Implementierung. Im Wesentlichen die Interna von Geth. Wir bemühen uns, Geth (als Ganzes oder in Teilen) als Bibliothek in anderen Projekten zu verwenden. Bezüglich Python kann ich nicht wirklich helfen. Keine Ahnung.
Danke Peter. Ich suchte nach einer einfachen ausführbaren Datei, um das zu tun. Das wird mein Ausgangspunkt sein.
Welche cryptoBibliothek meinst du hier? Kannst du auch auf deine typesDatei verlinken?

Sie können Web3 verwenden .

var Accounts = require('web3-eth-accounts');

// Passing in the eth or web3 package is necessary to allow retrieving chainId, gasPrice and nonce automatically
// for accounts.signTransaction().
// var accounts = new Accounts('ws://localhost:8546');
var accounts = new Accounts();
// if nonce, chainId, gas and gasPrice is given it returns synchronous
accounts.signTransaction({
    to: '0xF0109fC8DF283027b6285cc889F5aA624EaC1F55',
    value: '1000000000',
    gas: 2000000,
    gasPrice: '234567897654321',
    nonce: 0,
    chainId: 1
}, '0x4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318')

Ausgabe:

{
    messageHash: '0x6893a6ee8df79b0f5d64a180cd1ef35d030f3e296a5361cf04d02ce720d32ec5',
    r: '0x09ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9c',
    s: '0x440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428',
    v: '0x25',
    rawTransaction: '0xf86a8086d55698372431831e848094f0109fc8df283027b6285cc889f5aa624eac1f55843b9aca008025a009ebb6ca057a0535d6186462bc0b465b561c94a295bdb0621fc19208ab149a9ca0440ffd775ce91a833ab410777204d5341a6f9fa91216a6f3ee2c051fea6a0428'
}

Verwenden Sie einfach rawTransaction.

Quellcode

Ihre Antwort hat mich dazu inspiriert, ein kleines Skript dafür zu schreiben, das eine Keystore-Datei dekodiert. Es ist unter gist.github.com/neuhaus/7387edf411513a9f11f1242dcec8d62e

Ich habe einen Weg gefunden, die Pyethereum-Bibliothek zu verwenden .

Übrigens, diese Bibliothek hat wenig Wartung und kann nicht in die meisten Betriebssysteme eingebaut werden.

Hier ist der Beispielcode dafür:

from libs.pyethereum.ethereum import transactions
from libs.pyethereum.ethereum import utils

# Create the priv keys and addresses. Addresses are returned in bytearray
key = utils.sha3("this is an insecure passphrase")
key2 = utils.sha3("37Dhsg17e92dfghKa Th!s i$ mUcH better r920167dfghjiHFGJsbcm")
addr = utils.privtoaddr(key)
addr2 = utils.privtoaddr(key2)

# Bytearray addresses
addr
'\xb8\xa1\xe7\x0b\x90\xb2\x8c\xde\x1e\xf7@+\xc2\x80\xc5\xb5\xa3W\xb4\x99'
addr2
'R~\xde {\x07"\xde\xfd\x981\x84\xcdA\x81\xbe\x82b\xdf\x01'

# Encoding the addresses in hex
addr_hex = utils.decode_addr(addr)
addr_hex
'b8a1e70b90b28cde1ef7402bc280c5b5a357b499'
addr2_hex = utils.decode_addr(addr2)
addr2_hex
'527ede207b0722defd983184cd4181be8262df01'
# These addresses are better represented with a '0x' prefix


# Create a transaction using key (address 1 priv key) and addr2 in bytearray
tx = transactions.Transaction(0, 1000, 100000, addr2, 56789000, "").sign(key)
tx.to_dict()
{'nonce': 0,
'hash': '648f97b1127bd26e5aa2f9b19d711648cb42509f105fd1ac4c90314c60bb06b1',
'sender': '\xb8\xa1\xe7\x0b\x90\xb2\x8c\xde\x1e\xf7@+\xc2\x80\xc5\xb5\xa3W\xb4\x99',
'startgas': 100000, 'value': 56789000, 'to': 'R~\xde {\x07"\xde\xfd\x981\x84\xcdA\x81\xbe\x82b\xdf\x01',
's': 27174000365690764914673576881913711980121871729925928151256478086834586258233L,
'r': 38109765815193709364550029305417348322702924861956728590268128554533127943524L,
'v': 28L, 'data': '', 'gasprice': 1000
}
Wie würde die Transaktion aussehen, wenn ich die Transaktion zusammenstellen möchte, um eine Zustandsänderungsfunktion eines Vertrags aufzurufen? Wie und wo würde ich die Argumente zur Funktion des Vertrages angeben.

Ich habe einen vollständigen Python-Code geschrieben. Fühlen Sie sich frei zu verwenden:

def signTransaction(to, value, privkey, nonce=0, gasPrice=20000000000, gas=21000, data=""):
    from ethereum import transactions
    import rlp
    try:
        return { 'error':False, 'sign':rlp.encode(transactions.Transaction(nonce, gasPrice, gas, to, value, data).sign(privkey)).encode('hex') }
    except Exception as msg:
        return { 'error':True, 'message':msg }

Hier ist eine JavaScript-Befehlszeilenanwendung zum Erstellen von Offline-Transaktionen. Sie können auch den vollständigen Tutorial-Blogbeitrag lesen .

  • Offline wie in Ihrem privaten Schlüssel verlässt niemals Ihren Computer

  • Es verwendet den Dienst etherscan.io, um den neuesten Nonce- und Gaspreis zu erhalten

  • Sie können zusätzlich einen Vertragsfunktionsaufruf und Argumente angeben

Code:

  /**
   * Sign an Ethereum transaction offline.
   *
   *
   * To run:
   *
   *   nvm use 7.2.1
   *   ./node_modules/babel-cli/bin/babel-node.js --presets es2015 --plugins transform-async-to-generator ./src/offlinetx.js --private-key 0xaaaaaaaaaaaaaaaaaaa --value 0.95 --to 0xAaF2ac6b800398F671b0D24cb8FccC3897B6aE49 --api-key HHHHHHHHHHHHHHHHHHHHHH

   *
   */

  import Web3 from 'web3'; // https://www.npmjs.com/package/web3
  import argv from 'optimist';
  import {buildTx, getAddressFromPrivateKey} from './txbuilder';
  import {API} from './etherscan';

  let web3 = new Web3();

  let _argv = argv.usage("offlinetx $0 --api-key 0x0000000 --private-key 0x00000000000000 --value 1.20 --to 0x1231231231")
    .describe("value", "Transaction amount in ETH")
    .describe("private-key", "32 bytes private key has hexadecimal format")
    .describe("to", "Ethereum 0x address where to send")
    .describe("nonce", "Nonce as hexacimal format, like 0x1")
    .describe("api-key", "etherscan.io API key used to get network status")
    .describe("gas-limt", "Maximum gas limit for the transaction as a hexadecmial")
    .default("gas-limit", web3.toHex(200000))
    .string("private-key")  // Heurestics is number by default which doesn't work for bigints
    .string("to")
    .string("api-key")
    .string("value")
    .string("nonce")
    .string("gas-limit")
    .demand(["private-key", "value", "to"]);

  async function run(argv) {

    // Parse command line
    let apiKey = argv["api-key"];
    let privateKey = argv["private-key"];
    let value = argv["value"];
    let to = argv["to"];
    let nonce = argv["nonce"];
    let gasLimit = argv["gas-limit"];

    if(!privateKey) {
      console.error("No private key given");
      process.exit(1);
    }

    if(!apiKey) {
      console.error("No EtherScan.io API key given");
      process.exit(1);
    }

    // Build EtherScan.io API wrapper object
    const api = new API("https://api.etherscan.io/api", apiKey);

    let fromAddress = getAddressFromPrivateKey(privateKey);

    // If nonce is not given get it usig Etherscan
    if(!nonce) {
      nonce = await api.getTransactionCount(fromAddress);
    }

    let gasPrice = await api.getGasPrice();

    value = web3.toHex(web3.toWei(value, "ether"));

    // What goes into our transaction
    let txData = {
      contractAddress: to,
      privateKey: privateKey,
      nonce: nonce,
      functionSignature: null, // TODO: Add contract call support here
      functionParameters: null,
      value: value,
      gasLimit: gasLimit,
      gasPrice: gasPrice,
    };

    // User readable output
    let info = Object.assign({}, txData);
    info.fromAddress = fromAddress;
    info.gasLimitInt = parseInt(txData.gasLimit, 16);
    info.gasPriceInt = parseInt(txData.gasPrice, 16);
    info.weiValueInt = parseInt(txData.value, 16);
    console.log("Building transaction with parameters\n", info);

    let tx = buildTx(txData);

    console.log("Your raw transaction is: ", tx);
    console.log("Visit at https://etherscan.io/pushTx to broadcast your transaction.");

  }

  run(_argv.argv)
    .catch(function(e) {
      console.error(e);
    });