6

Given a private key, I would like to sign a transaction offline, so it can be sent to a node or Infura without unlocking an account first. I can find many examples in javascript using ethereumjs-tx but I am using Rust and rust-web3 and can't find a single example that writes data. I need to be able to call functions, not just send value, so how to construct the function parameters is of particular interest. Also, how can I wait and process the return value if the function has a return value?

3 Answers 3

4

It is a function of wallet to store and use your private key. web3 API like rust-web3 usually leave transaction signing to wallet. Therefore your option is to reuse the code in Ethereum wallets that are written in Rust.

1
  • 1
    I spoke to the rust-web3 author and he said it is not yet supported but would be great to add. For now, there is an open issue filed for the project. Thanks for the link to Emerald. There is lots of Rust code in the Parity repo we have been leveraging as well.
    – emkman
    Commented May 15, 2018 at 19:14
4

There is a package for this called ethereum-tx-sign on crates.io. It provides a RawTransaction structure with a sign method. It doesn't have any dependency on web3 and you can sign the transactions offline.

1
  • Thanks, this didn't exist at the time of posting. A welcome addition to the rust eth ecosystem!
    – emkman
    Commented Nov 27, 2018 at 9:24
3

There's a trick using python's web3 package with cpython:

let gil = Python::acquire_gil();
let py = gil.python();
let web3 = py.import("web3").unwrap();

let transaction = {
    let transaction = PyDict::new(py);
    transaction.set_item(py, "gas", gas_limit).unwrap();
    transaction.set_item(py, "gasPrice", gas_price).unwrap();
    transaction.set_item(py, "nonce", nonce).unwrap();
    transaction.set_item(py, "data", data).unwrap();

    let web3 = web3.get(py, "Web3").unwrap();
    let to = web3.call_method(py, "toChecksumAddress", (to, ), None).unwrap();

    transaction.set_item(py, "to", to).unwrap();
    transaction.set_item(py, "value", value).unwrap();

    transaction
};

let account = web3.get(py, "Account").unwrap();
let signed_transaction = account.call_method(py, "signTransaction", (transaction, private_key), None).unwrap();

let raw_transaction: String = signed_transaction.getattr(py, "rawTransaction")
    .unwrap()
    .call_method(py, "hex", NoArgs, None)
    .unwrap()
    .extract(py)
    .unwrap();

Boom! Got it!

Btw, about ethereum-tx-sign. I've already try it, but it seems not work correctly. My target server doesn't recognize the signedRawTransaction. So I compare the its result with web3's result and I found they were different.

0

Your Answer

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

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