Closed tuxxy closed 5 years ago
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
This issue now has a funding of 1500.0 DAI (1500.0 USD @ $1.0/DAI) attached to it.
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
Work has been started.
These users each claimed they can complete the work by 6 months, 1 week from now. Please review their action plans below:
1) paulrberg has been approved to start work.
I previously built a few private networks and I'd love to contribute to geth! I've also got a decent understanding of cryptography used in Ethereum.
I'll start by clearly breaking down what currently can be done and what would be the first subproblems in implementing EIP-191.
Learn more on the Gitcoin Issue Details page.
2) moodysalem has applied to start work _(Funders only: approve worker | reject worker)_.
Learn more on the Gitcoin Issue Details page.
A few comments... The spec
eth_Sign
will be removed from geth. We're removing account management from geth
and moving it into clef
, which is a standalone binary solely for account/key management. I'm thinking that maybe the signer can, for now, only deal with certain subs of EIP-191, the first two being 0x45
and 0x01
.
This also ties in with some other work I'm doing for clef, namely the ability to sign Clique headers. One thing I'm pondering is to have accounts_sign(content_type, ... )
, where content-type can be e.g application/clique
or application/eip191
etc.
Here is some WIP, where I've been trying out how to fit various types of signing into clef
. See commit https://github.com/holiman/go-ethereum/commit/5b03e2029f4cd472f1167999fe6907614158ec81#diff-f8316f6ee7e75303007a55a1cde29245R420 in my branch geth_relay
.
While I'm all for someone taking charge of this and helping out the implementation, I fear that the brunt of the work is not in actual coding, but a lot will have to go into coordination and discussions. But yes, I'd approve @PaulRBerg to take this on
Okay so I had a thorough read on both the EIP-191 and EIP-712 specs, their adjacent[1][2] links and your Clique WIP and I confirm I am able to take on both tasks.
Thanks for the brief intro to clef
and for the accounts_sign
suggestion. Just to confirm, you're referring to having the following list of content-type
:
• application/clique
• application/eip191
• application/eip712
Where eip191
maps to the 0x00
and 0x45
version bytes and eip712
to 0x01
?
Re coordination - totally agree, the UX can be really easily a nightmare for the non-technical end user, thus I'd suggest, for now, asking wallets to only accept JSON compatible data which can be nicely presented just like here. Non-JSON could still be accepted, but with a warning saying "Your data is not JSON compatible. You can still sign it, but please be careful and double check". Furthermore, I see a potential cross over with ENS to make accounts look more human-readable.
Also, is there any Slack or Riot room focused specifically on geth and sigs? I think it'd be helpful to hang around there to keep discussions as lightweight as possible. I'll also try to DYOR as much as I can to avoid unnecessary questions.
We have a discord server: https://discord.gg/aBsXrzr . That server has a clef-channel, for all signing related stufd
Re content-types, nothing is set in stone, I have just tinkered a bit with how it could be done, to see if it makes sense
I want to point out the reason for opening this issue:
Currently, Ethereum signatures are sorta bad. EIP-191 and EIP-712 are the best we have right now and they have different usecases.
We need a way to sign data arbitrarily with an unlocked account for a long running process. We don't want to build a wallet because we don't think the ecosystem should be building one wallet per account type apps.
We also intend to integrate this with web3py for the Python/ETH ecosystem as well so we can use it in nucypher.
Thanks for jumping on this so quickly!
Currently, Ethereum signatures are sorta bad
Totally agree. Bad bordering useless.
It's great that you're jumping in, because I don't want to end up building an API endpoint that does not fit the usecase it's intended for, so it would be good to have some more info on e.g. how you would like to call it. While 712 has an example, the 191 spec (which I'm a co-author of) doesn't currently have any examples on the API-side for how the corresponding signing methods should look. I'm thinking that a starting point would be to implement 191/172
but return errors for other 191 subtypes (until those get specced and implemented)
And btw: unlock
is being nuked from orbit, but a semi-advanced user will be able to set rules allowing certain types of operation automatically, such as e..g signing a certain type of data.
Awesome to see so much conversation about this already! @holiman are you already in discussions with Paul via Discord? Alright on your end if I accept him for this bounty?
@ceresstation yup fine by me
Currently, Ethereum signatures are sorta bad. EIP-191 and EIP-712 are the best we have right now and they have different usecases.
Gotcha.
We also intend to integrate this with web3py for the Python/ETH ecosystem as well so we can use it in nucypher.
I totally acknowledge that and it's really exciting to contribute to so many projects at once. I'll aim to be the author of the PRs for we3b (js and py).
so it would be good to have some more info on e.g. how you would like to call it.
Before doing any coding, I'll devise a short but effective strategy. Doing a lot of research across many ethereum repos now.
I have a few other quick questions, but I'll defer them to Discord to keep this thread only for significant updates. Thank you @holiman @tuxxy @ceresstation!
Hey there, a fresh update, I created a small repo documenting my latest research: https://github.com/PaulRBerg/ethereum-signatures-progress
There's a list of resources and projects which have already tinkered with EIP-191 and EIP-712. Thanks to @cooganb for reaching out on Discord to mention their work on a basic login system adhering to 191.
I'll constantly update the registries in there as there is significant progress. As geth
itself is concerned, I delved into its meat, playing around and analysing clef
, rpc
and signer
. Strategy:
signer
as that's where the standards should be coded in0x45
and returns a hardcoded message for 0x01
. Will iterate fast and continue from there.Just to confirm, the signing methods should be available both in clef
in the CLI and in RPC via clef_signTypedData
? Or, for the JSON-RPC, is it that other prefix should be used (clef
is not currently listed in the wiki)?
UPDATE: no answer needed anymore. I sorted it out, clef is using the account
prefix as per the README.
Great work @PaulRBerg ! Let me know if I can help with anything.
Significant update: https://github.com/ethereum/go-ethereum/pull/17789
@PaulRBerg Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!
Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days
I have just pushed an update on #17789 which implements a skeleton for testing the content types:
go test -v -cpu 4 ./signer/core -run TestSignData
Now, we have to sort out:
0x45
or data/plain
is okaytext/plain
instead of data/plain
and the order on thatecRecover
function, although not usable for all signing typesLatest work is on https://github.com/PaulRBerg/go-ethereum/tree/eip-191/712_wip
Getting close. Currently working on handling the params sent with a JSON-RPC call and validating them against the EIP-712 specs.
I'm also curious to see what apps will there be develope at EthSF and get in touch with the devs to see what would be the best solution for point 3 above.
@PaulRBerg Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!
Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days
Hi there, I participated at EthSF, but still worked on these EIPs on the side. Currently tweaking the rpc/http
and rpc/server
code to make it work with the arbitrary key values required by EIP-712. You can find my latest work at https://github.com/PaulRBerg/go-ethereum/tree/eip191/712_wip
The problem specifically is that the geth rpc server should accept a new struct called TypedData
but it returns empty maps: map[] map[] map[]
when querying eth_signStructuredData
. Here's the struct definition, POST data and response:
type TypedData struct {
Types map[string] interface{} `json:"types"`
PrimaryType string `json:"primaryType"`
Domain map[string] interface{} `json:"domain"`
Message map[string] interface{} `json:"message"`
}
{
"jsonrpc": "2.0",
"method": "account_signStructuredData",
"params": [
"0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826",
{
"types": {
"EIP712Domain": [
{
"name": "name",
"type": "string"
},
{
"name": "version",
"type": "string"
},
{
"name": "chainId",
"type": "uint256"
},
{
"name": "verifyingContract",
"type": "address"
}
],
"Person": [
{
"name": "name",
"type": "string"
},
{
"name": "wallet",
"type": "address"
}
],
"Mail": [
{
"name": "from",
"type": "Person"
},
{
"name": "to",
"type": "Person"
},
{
"name": "contents",
"type": "string"
}
]
},
"primaryType": "Mail",
"domain": {
"name": "Ether Mail",
"version": "1",
"chainId": 1,
"verifyingContract": "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC"
},
"message": {
"from": {
"name": "Cow",
"wallet": "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826"
},
"to": {
"name": "Bob",
"wallet": "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB"
},
"contents": "Hello, Bob!"
}
}
],
"id": 1
}
fmt.Println("data", data)
// output after RPC call is `data {map[] map[] map[]}`
Specifically, I'm trying to make it work as explained in this StackOverflow thread. Someone pointed me that eth_getLogs is similar, will check that out.
I tried only with a basic struct and it still doesn't parse it correctly:
type TypedData struct {
PrimaryType string `json:"primaryType"`
}
fmt.Println("data.PrimaryType", data.PrimaryType)
// output after RPC call is `data.PrimaryType`
Currently investigating how crit FilterCriteria
is parsed in func (api *PublicFilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*types.Log, error)
in eth/filters/api.go
. There must be some fundamental differences in the core codecs used.
Figured it out by reading lines 274-276 from eth/filters/api.go
:
// FilterCriteria represents a request to create a new filter.
// Same as ethereum.FilterQuery but with UnmarshalJSON() method.
type FilterCriteria ethereum.FilterQuery
Now writing the custom UnmarshalJSON() function for TypedData
.
@PaulRBerg Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!
Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days
Major update, check it out on #17789.
TypedData
issue I had with the JSON-RPC server (thank you @holiman)contentType
mimes back to the defaults of EIP-191. Just for the record, the table below mirrors what's now defined on the PR page.encodeType
function for EIP-712.In this specific PR, there are a few debugging logs but please neglect them as they'll be scratched soon. For EIP-712, pretty much only encodeData
is left and we're good to go to test it out until it breaks.
Version byte | Name | Description |
---|---|---|
0x00 |
text/validator | Data with intended validator |
0x01 |
data/typed | EIP-712 typed data |
0x02 |
application/clique | Clique headers |
0x45 |
text/plain | Plain, personal messages |
A new update on #17789 implements a recursive hashStruct
in coalition with encodeData
, but the latter still needs type handling. Most probably the current model of verifying the type in go directly should be changed with checking the types object (the strings themselves) sent along the data via JSON-RPC.
@PaulRBerg Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!
Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days
EIP-712 is almost implemented. Big updates in this repo: https://github.com/PaulRBerg/codebase-go/tree/master/eip712
I switched there for the last few days as testing is faster.
The first drafted version of EIP-712 is implemented in the last update on #17789! Accompanying tests were written. Important question:
Should I generate a slice of arguments (that is, []pack.Argument
) and then run them through the Pack
function in the abi
package instead of manually doing the encoding? Currently, I'm adding empty bytes to match the 32-bytes requirement for bytes1:31
and uint160
.
@PaulRBerg Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!
Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days
Please snooze this, he's doing good progress on this!
Thank you @holiman! Just for the record, I'm currently waiting for feedback on the latest drafts, but, at the same time, I pushed a commit yesterday which solves a few known bugs. Everything can be tracked on PR #17789.
@PaulRBerg Hello from Gitcoin Core - are you still working on this issue? Please submit a WIP PR or comment back within the next 3 days or you will be removed from this ticket and it will be returned to an ‘Open’ status. Please let us know if you have questions!
Funders only: Snooze warnings for 1 day | 3 days | 5 days | 10 days | 100 days
It was great catching up with @holiman in Prague as we were able to discuss the last details for implementing EIP-191 and EIP-712. I absolutely enjoyed working on this - and now I can say that PR #17789 is done and pending for feedback from your end :)
Overview:
• Method eth_signData
accepts a contentType
parameter which fully adheres to the specs of EIP-191
• Method eth_signTypedData
accepts a typedData
json object conforming to EIP-712
I eventually separated the methods because (1) that's what the specs require and (2) there were a lot of assumptions in converting a map[string]interface{}
to a TypedData
object. It is much easier to let the rpc
server deal with that via its built-in reflections.
Aiming to also get in touch with the EIP-712 authors to see if they could take a look.
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
Work for 1500.0 DAI (1500.0 USD @ $1.0/DAI) has been submitted by:
@ceresstation please take a look at the submitted work:
This PR implements this: https://github.com/ethereum/go-ethereum/pull/17789
Should this issue be closed?
Issue Status: 1. Open 2. Started 3. Submitted 4. Done
The funding of 1500.0 DAI (1500.0 USD @ $1.0/DAI) attached to this issue has been approved & issued to @PaulRBerg.
Does this need to be closed now?
Geth lacks an API to perform an EIP-191 conforming signature for a given unlocked account. An API should be implemented that allows for arbitrary data to be signed by a specified unlocked account. This API will encompass signing as well as verifying functionalities.
Current API: https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign