mirror of
https://github.com/status-im/contracts.git
synced 2025-02-23 03:58:42 +00:00
Basic ecrecovery example added.
This commit is contained in:
parent
5dae7874ff
commit
3ebfbd7f27
28
contracts/ecrecovery.eg.py
Normal file
28
contracts/ecrecovery.eg.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import pytest
|
||||||
|
|
||||||
|
from ethereum import utils
|
||||||
|
from tests.setup_transaction_tests import chain as s, tester as t, ethereum_utils as u, check_gas, \
|
||||||
|
get_contract_with_gas_estimation, get_contract
|
||||||
|
|
||||||
|
|
||||||
|
def sign(message, key):
|
||||||
|
_hash = utils.sha3(message)
|
||||||
|
return _hash, utils.ecsign(_hash, key)
|
||||||
|
|
||||||
|
|
||||||
|
_hash, sigdata = sign("test message", t.k0)
|
||||||
|
v, r, s = sigdata
|
||||||
|
sig = utils.encode_int32(r) + utils.encode_int32(s) + utils.encode_int(v)
|
||||||
|
|
||||||
|
|
||||||
|
code = """
|
||||||
|
def extract_v(sig: bytes <= 66) -> num256:
|
||||||
|
s = slice(sig, start=64, len=1)
|
||||||
|
return as_num256(bytes_to_num(s))
|
||||||
|
"""
|
||||||
|
code = """
|
||||||
|
def extract_v(sig: bytes <= 96) -> bytes <= 96:
|
||||||
|
return slice(sig, start=64, len=1)
|
||||||
|
"""
|
||||||
|
c = get_contract(code)
|
||||||
|
c.extract_v(sig)
|
28
contracts/ecrecovery.v.py
Normal file
28
contracts/ecrecovery.v.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# Viper verify ecrecovery function.
|
||||||
|
|
||||||
|
|
||||||
|
owner: address
|
||||||
|
|
||||||
|
|
||||||
|
def __init__():
|
||||||
|
self.owner = msg.sender
|
||||||
|
|
||||||
|
|
||||||
|
def sigdata_verify(h: bytes32, sigdata: num256[3]) -> bool:
|
||||||
|
if ecrecover(h, sigdata[0], sigdata[1], sigdata[2]) == self.owner:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def sig_verify(h: bytes32, sig: bytes <= 66) -> bool:
|
||||||
|
|
||||||
|
r = extract32(sig, 0, type=num256)
|
||||||
|
s = extract32(sig, 32, type=num256)
|
||||||
|
sliced = slice(sig, start=64, len=1)
|
||||||
|
v = as_num256(bytes_to_num(sliced))
|
||||||
|
|
||||||
|
if ecrecover(h, r, s, v) == self.owner:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
@ -1,7 +1,19 @@
|
|||||||
|
# Key management types
|
||||||
keys: address[20]
|
keys: address[20]
|
||||||
key_types: num[20]
|
key_types: num[20]
|
||||||
key_count: num
|
key_count: num
|
||||||
|
claim_count: num
|
||||||
|
|
||||||
|
# Claim types
|
||||||
|
claims: {
|
||||||
|
claimId: bytes32,
|
||||||
|
claimType: num,
|
||||||
|
issuer: address,
|
||||||
|
signatureType: num,
|
||||||
|
signature: bytes <= 4096,
|
||||||
|
data: bytes <= 4096,
|
||||||
|
uri: bytes <= 4096
|
||||||
|
}[num]
|
||||||
|
|
||||||
|
|
||||||
def __init__():
|
def __init__():
|
||||||
@ -100,3 +112,57 @@ def replaceKey(_oldKey: address, _newKey: address) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The signature format is a compact form of:
|
||||||
|
# {bytes32 r}{bytes32 s}{uint8 v}
|
||||||
|
# Compact means, uint8 is not padded to 32 bytes.
|
||||||
|
@internal
|
||||||
|
def sig_verify(h: bytes32, signer: address, sig: bytes <= 66) -> bool:
|
||||||
|
r = extract32(sig, 0, type=num256)
|
||||||
|
s = extract32(sig, 32, type=num256)
|
||||||
|
sliced = slice(sig, start=64, len=1)
|
||||||
|
v = bytes_to_num(sliced)
|
||||||
|
|
||||||
|
# geth uses [0, 1] and some clients have followed.
|
||||||
|
# Add 27 to make it v compatible.
|
||||||
|
if v < 27:
|
||||||
|
v += 27
|
||||||
|
assert v == 27 or v == 28
|
||||||
|
|
||||||
|
if ecrecover(h, r, s, as_num256(v)) == signer:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def addClaim(_claimType: num(num256), issuer: address, signatureType: num(num256),
|
||||||
|
_signature: bytes <= 4096, _data: bytes <= 4096, _uri: bytes <= 4096) -> bytes32:
|
||||||
|
# For the time being assume singatureType == 1 means use ecrecover to verify.
|
||||||
|
# Also we only allow EC verify in this contract.
|
||||||
|
assert signatureType == 1
|
||||||
|
|
||||||
|
_id = sha3(concat(as_bytes32(_claimType), as_bytes32(issuer), as_bytes32(signatureType), _data, _uri))
|
||||||
|
|
||||||
|
if self.sig_verify(_id, issuer, slice(_signature, start=0, len=65)):
|
||||||
|
self.claims[0] = {
|
||||||
|
claimId: _id,
|
||||||
|
claimType: _claimType,
|
||||||
|
issuer: issuer,
|
||||||
|
signatureType: signatureType,
|
||||||
|
signature: _signature,
|
||||||
|
data: _data,
|
||||||
|
uri: _uri
|
||||||
|
}
|
||||||
|
return _id
|
||||||
|
else:
|
||||||
|
throw
|
||||||
|
|
||||||
|
# Outstanding:
|
||||||
|
# function getClaim(bytes32 _claimId) constant returns(uint256 claimType, address issuer, uint256 signatureType, bytes signature, bytes data, string uri);
|
||||||
|
# function getClaimIdsByType(uint256 _claimType) constant returns(bytes32[] claimIds);
|
||||||
|
# function removeClaim(bytes32 _claimId) returns (bool success)
|
||||||
|
|
||||||
|
# function addClaim(uint256 _claimType, address issuer, uint256 signatureType,
|
||||||
|
# bytes _signature, bytes _data, string _uri) returns (bytes32 claimRequestId)
|
||||||
|
3
tests/test_ecrecovery.py
Normal file
3
tests/test_ecrecovery.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import pytest
|
||||||
|
from tests.setup_transaction_tests import chain as s, tester as t, ethereum_utils as u, check_gas, \
|
||||||
|
get_contract_with_gas_estimation, get_contract
|
Loading…
x
Reference in New Issue
Block a user