airalab / hs-web3

Web3 API for Haskell
http://hackage.haskell.org/package/web3
Apache License 2.0
189 stars 68 forks source link

Offnode transaction signer #10

Closed akru closed 6 years ago

akru commented 7 years ago

Currently library use full Ethereum nodes (like parity & geth) to sign & send transactions. It would be pretty good to add transaction signer into library for using public Ethereum nodes, like infura.

JS alternative is https://github.com/ethjs/ethjs-provider-signer.

aupiff commented 6 years ago

To use an offnode signer, one needs to send a private key over HTTP. If a user already has access to a cleartext private key, he may as well sign the transaction himself. I am using a library I wrote for this, ethereumhs-util. By setting a Provider to point to Infura or whatever service a user likes, a user can query his account's transaction count (the nonce), sign his transaction and finally sendRawTransaction to Infura. This solution will require very few changes to the code. What do you think?

I'll write a demo of how this will work in the documentation of my ethereumhs-util library. (The library is still a bit rough, I'll have to clean it up this weekend.)

akru commented 6 years ago

Great! It seems like web3.js approach. What do you think about copying Network.Ethereum.Utils with tests to hs-web3? From the first view, troubles can be raised with secp256k1 library deps.

aupiff commented 6 years ago

I was thinking that there need to exist at least four different libraries:

1) ethereum-types that contains both general ethereum types like Address, and more specific Solidity types like Uint256 and Int256. (eventually, we may need to split a piece off into a separate solidity-types)

2) ethereumhs-util that contains useful cryptographic functions for hashing, pub/privkey manipulation, signatures, etc.

3) hs-web3 for web3 interactions

4) ethereum-wallet for key management including sophisticated HD wallet functionality with mnemonics


As these libraries are written, I also want to write pure Haskell implementations of Keccak256 hashing and basic secp256k1 functionality to remove all C dependencies; this will make the code usable on the frontend via ghcjs.

These libraries can be housed in a single organization like EthereumJS, but for the Haskell Ethereum community. Would you like to work on something like this?

I've just created an organization called hasketh that I'll invite you to.

https://github.com/hasketh

akru commented 6 years ago

I'm not sure that splitting to more that one repos is good practice at current stage, community of library is very small now. In this scenario we can unfortunately make library without batteries, because maintaining lots of packages burn your time. At current stage I interested in making small stable library for ethereum with batteries included.

aupiff commented 6 years ago

OK, that makes sense. I'll copy Network.Ethereum.Util into this library when I'm ready to implement signing.

akru commented 6 years ago

Great thanks for contribution, waiting for you changes.

akru commented 6 years ago

@aupiff Hi! Do you currently make this feature?

aupiff commented 6 years ago

@akru Hello! I'll make sure to get this done over the weekend.

akru commented 6 years ago

Sounds great! Waiting for your changes, thanks!

aupiff commented 6 years ago

Sorry for the delay on this feature, I'll do my best to finish by the end of next week.

akru commented 6 years ago

Pretty good @aupiff, thank you!

aupiff commented 6 years ago

I've been successfully signing transactions with some code that I have in a very messy branch here: https://github.com/aupiff/hs-web3/blob/offline-sign/src/Network/Ethereum/Transaction.hs#L37-L61

The issue is deciding how to sign transactions that are generated by TH.hs; currently, I've changed funWrapper to generate functions that generate a Call type for non-constant abi methods. See:

https://github.com/aupiff/hs-web3/blob/offline-sign/src/Network/Ethereum/Web3/TH.hs#L201-L205 https://github.com/aupiff/hs-web3/blob/offline-sign/src/Network/Ethereum/Web3/Contract.hs#L290-L301

What do you think the approach should be for offline signing of transactions generated by this meta-programmed code? Perhaps there should be functions generated for all abi methods called {abiFunctionName}Call which are then wrapped by either an Eth.sendTransaction or Eth.call depending on if they're constant or not. These functions would be called {abiFunctionName} like is currently done so these changes would be backwards compatible.

akru commented 6 years ago

Hi!

Seems good, in my opinion we can detect preferred user transaction send method from Provider data type. For example, like this:

data Provider = Provider {
  jsonRpc = JsonRpcProvider
  account = Maybe PrivateKey
}

If private key is set we can wrap methods in one way and sign txs by self but if it isn’t set we try to sign txs via JSON-RPC by ethereum node.

aupiff commented 6 years ago

Sounds good, I'll try this approach.

akru commented 6 years ago

Hello @aupiff! Do you have any updates? Can I plan to integrate your feature in future release?

aupiff commented 6 years ago

Sorry, was busy with work for a few weeks. I'll finish this up by May 9th though I hope I'll be able to submit a draft PR by this Friday.

akru commented 6 years ago

Thank you for your contribution @aupiff! Have a nice day!

akru commented 6 years ago

Ok, I merge #61 and currently work on big release around hs-web3 accounts (like web3py accounts).

Thank you for your work, @aupiff!