tomusdrw / rust-web3

Ethereum JSON-RPC multi-transport client. Rust implementation of web3 library. ENS address: rust-web3.eth
MIT License
1.45k stars 465 forks source link

EIP712 #169

Open BlinkyStitt opened 5 years ago

BlinkyStitt commented 5 years ago

I'm wanting to hash 0x orders and they use EIP712. I'm trying to write this in rust and not javascript. Is this currently possible with rust-web3?

tomusdrw commented 5 years ago

@WyseNynja We don't have that method exposed yet (PRs welcome!). You can freely extend rust-web3 though, you will just need to define all the input and output types and their deserialization.

That3Percent commented 4 years ago

There is a separate crate which may fit the bill here: eip-712

gakonst commented 4 years ago

Doesn't that conflict with this library's MIT license?

tomusdrw commented 4 years ago

@gakonst Correct, the crate mentioned here can't really be included in web3, but you are fine to build a GPL-3.0 project that uses both web3 and eip-712 to achieve what you need.

That3Percent commented 4 years ago

Dismayed by the licensing, I went ahead to build a replacement for the GPL licensed eip-712 crate that is MIT licensed and is based on structs instead of JSON. It's not yet batteries included, but you can see examples of how to use it in the tests section.

https://github.com/graphprotocol/eip-712-derive

Example usage:

struct Mail {
    from: Person,
    to: Person,
    contents: String,
}
// This is all that is necessary to implement any EIP-712 signable struct
impl StructType for Mail {
    const TYPE_NAME: &'static str = "Mail";
    fn visit_members<T: MemberVisitor>(&self, visitor: &mut T) {
        visitor.visit("from", &self.from);
        visitor.visit("to", &self.to);
        visitor.visit("contents", &self.contents);
    }
}

/* Elided Person struct, etc */

fn test() -> (Signature, RecoveryId) {
 let domain = DomainStruct {
        name: "Ether Mail".to_owned(),
        version: "1".to_owned(),
        chain_id: chain_id::MAIN_NET,
        verifying_contract: Address(
            (&(hex::decode("CcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC").unwrap())[..])
                .try_into()
                .unwrap(),
        ),
    };
let domain_separator = DomainSeparator::new(&domain);
let message = Mail {
        from: Person { /* elided */ },
        to: Person { /* elided */ },
        contents: "Hello, Bob!".to_owned(),
    };
 sign_typed(&domain_separator, &message, &pk)
}