def ecrecover(msg, signature, address=None): """ Returns None on failure, returns the recovered address on success. If address is provided: Returns True if the recovered address matches it, otherwise False. """ rawhash = sha3(msg) if len(signature) >= 65: v = safe_ord(signature[64]) + 27 r = big_endian_to_int(signature[0:32]) s = big_endian_to_int(signature[32:64]) else: if address: return False else: return None pk = PublicKey(flags=ALL_FLAGS) pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32), v - 27), raw=True) pub = pk.serialize(compressed=False) recaddr = data_encoder(sha3(pub[1:])[-20:]) if address: if not address.startswith("0x"): recaddr = recaddr[2:] return recaddr == address return recaddr
def recover_sender(self): if self.v: if self.r >= N or self.s >= P or self.v < 27 or self.v > 28 \ or self.r == 0 or self.s == 0: raise InvalidSignature() rlpdata = rlp.encode(self, self.__class__.exclude(['v', 'r', 's'])) rawhash = sha3(rlpdata) pk = PublicKey(flags=ALL_FLAGS) try: pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( zpad( "".join( chr(c) for c in int_to_32bytearray(self.r)), 32) + zpad( "".join( chr(c) for c in int_to_32bytearray(self.s)), 32), self.v - 27), raw=True) pub = pk.serialize(compressed=False) except Exception: raise InvalidSignature() if pub[1:] == "\x00" * 32: raise InvalidSignature() pub = encode_pubkey(pub, 'bin') return sha3(pub[1:])[-20:]
def sign(self, payload): rawhash = keccak256(payload) v, r, s = ecsign(rawhash, self.key) signature = \ zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + \ zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32) + \ bytearray_to_bytestr([v]) return signature
def sign_payload(private_key, payload): if isinstance(private_key, str): private_key = data_decoder(private_key) rawhash = sha3(payload) v, r, s = ecsign(rawhash, private_key) signature = zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + \ zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32) + \ bytearray_to_bytestr([v]) return data_encoder(signature)
def personal_sign(private_key, message): if isinstance(private_key, str): private_key = data_decoder(private_key) rawhash = sha3("\x19Ethereum Signed Message:\n{}{}".format(len(message), message)) v, r, s = ecsign(rawhash, private_key) signature = zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32) + \ zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32) + \ bytearray_to_bytestr([v]) return data_encoder(signature)
def sender(self): if not self._sender: # Determine sender if self.v: if self.r >= N or self.s >= N or self.v < 27 or self.v > 28 \ or self.r == 0 or self.s == 0: raise InvalidTransaction("Invalid signature values!") log.debug('recovering sender') rlpdata = rlp.encode(self, UnsignedTransaction) rawhash = utils.sha3(rlpdata) pk = PublicKey(flags=ALL_FLAGS) try: pk.public_key = pk.ecdsa_recover( rawhash, pk.ecdsa_recoverable_deserialize( zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.r)), 32) + zpad(utils.bytearray_to_bytestr(int_to_32bytearray(self.s)), 32), self.v - 27 ), raw=True ) pub = pk.serialize(compressed=False) except Exception: raise InvalidTransaction("Invalid signature values (x^3+7 is non-residue)") if pub[1:] == b"\x00" * 32: raise InvalidTransaction("Invalid signature (zero privkey cannot sign)") pub = encode_pubkey(pub, 'bin') self._sender = utils.sha3(pub[1:])[-20:] assert self.sender == self._sender else: self._sender = 0 return self._sender
def decode_single(typ, data): base, sub, _ = abi.process_type(typ) if base == "address": return "0x" + data[-40:] elif base == "string" or base == "bytes" or base == "hash": if sub: bytes = ethereum_utils.int_to_32bytearray(int(data, 16)) while bytes and bytes[-1] == 0: bytes.pop() if bytes: return "".join(chr(b) for b in bytes) else: num_bytes = int(data[64 + 2 : 128 + 2], 16) bytes_as_hex = data[2 + 128 : 2 + 128 + (2 * num_bytes)] return ethereum_utils.decode_hex(bytes_as_hex) elif base == "uint": return int(data, 16) elif base == "int": o = int(data, 16) return (o - 2 ** int(sub)) if o >= 2 ** (int(sub) - 1) else o elif base == "ureal": raise NotImplementedError("havent gotten to this") high, low = [int(x) for x in sub.split("x")] # return big_endian_to_int(data) * 1.0 / 2 ** low elif base == "real": raise NotImplementedError("havent gotten to this") high, low = [int(x) for x in sub.split("x")] # return (big_endian_to_int(data) * 1.0 / 2 ** low) % 2 ** high elif base == "bool": return bool(int(data, 16)) else: raise ValueError("Unknown base: `{0}`".format(base))
def decode_single(typ, data): base, sub, _ = abi.process_type(typ) if base == 'address': return '0x' + data[-40:] elif base == 'string' or base == 'bytes' or base == 'hash': bytes = ethereum_utils.int_to_32bytearray(int(data, 16)) while bytes and bytes[-1] == 0: bytes.pop() if bytes: return ''.join(chr(b) for b in bytes) elif base == 'uint': return int(data, 16) elif base == 'int': o = int(data, 16) return (o - 2 ** int(sub)) if o >= 2 ** (int(sub) - 1) else o elif base == 'ureal': raise NotImplementedError('havent gotten to this') high, low = [int(x) for x in sub.split('x')] # return big_endian_to_int(data) * 1.0 / 2 ** low elif base == 'real': raise NotImplementedError('havent gotten to this') high, low = [int(x) for x in sub.split('x')] # return (big_endian_to_int(data) * 1.0 / 2 ** low) % 2 ** high elif base == 'bool': return bool(int(data, 16)) else: raise ValueError("Unknown base: `{0}`".format(base))
def extract_bytes(mem, start, sz): end = start + sz sminor, smajor = start & 31, start >> 5 eminor, emajor = end & 31, end >> 5 if not sz: return [] elif smajor == emajor: m = mem[smajor] o = utils.int_to_32bytearray(m)[sminor: eminor] else: m = utils.int_to_32bytearray(mem[smajor])[sminor:] for i in range((smajor) + 1, emajor): m.extend(utils.int_to_32bytearray(mem[i])) if eminor: m.extend(utils.int_to_32bytearray(mem[emajor])[:eminor]) o = m return o
def set_bytes(mem, start, bytez): end = start + len(bytez) sminor, smajor = start & 31, start >> 5 eminor, emajor = end & 31, end >> 5 if not bytez: pass elif (smajor) == (emajor): m = utils.int_to_32bytearray(mem[smajor]) mem[smajor] = utils.bytearray_to_int(m[:sminor] + bytez + m[eminor:]) else: if sminor: m = utils.int_to_32bytearray(mem[smajor]) mem[smajor] = utils.bytearray_to_int(m[:sminor] + bytez[:32 - (sminor)]) else: mem[smajor] = utils.bytearray_to_int(bytez[:32]) j = 0 for i in range((smajor) + 1, emajor): mem[i] = utils.bytearray_to_int(bytez[j + 32 - (sminor): j + 64 - (sminor)]) j += 32 if eminor: m2 = utils.int_to_32bytearray(mem[emajor]) endpiece = bytez[j + 32 - (sminor):] mem[emajor] = utils.bytearray_to_int(endpiece + m2[-32 + len(endpiece):])
def decode_single(typ, data): base, sub, _ = abi.process_type(typ) # ensure that we aren't trying to decode an empty response. assert len(data) > 2 if base == 'address': return '0x' + strip_0x_prefix(data[-40:]) elif base == 'string' or base == 'bytes' or base == 'hash': if sub: bytes = ethereum_utils.int_to_32bytearray(int(data, 16)) while bytes and bytes[-1] == 0: bytes.pop() if bytes: return ''.join(chr(b) for b in bytes) else: num_bytes = int(data[64 + 2:128 + 2], 16) bytes_as_hex = data[2 + 128:2 + 128 + (2 * num_bytes)] return ethereum_utils.decode_hex(bytes_as_hex) elif base == 'uint': return int(data, 16) elif base == 'int': o = int(data, 16) return (o - 2 ** int(sub)) if o >= 2 ** (int(sub) - 1) else o elif base == 'ureal': raise NotImplementedError('havent gotten to this') high, low = [int(x) for x in sub.split('x')] # return big_endian_to_int(data) * 1.0 / 2 ** low elif base == 'real': raise NotImplementedError('havent gotten to this') high, low = [int(x) for x in sub.split('x')] # return (big_endian_to_int(data) * 1.0 / 2 ** low) % 2 ** high elif base == 'bool': return bool(int(data, 16)) else: raise ValueError("Unknown base: `{0}`".format(base))
def decode_single(typ, data): base, sub, _ = abi.process_type(typ) # ensure that we aren't trying to decode an empty response. assert len(data) > 2 if base == 'address': return '0x' + strip_0x_prefix(data[-40:]) elif base == 'string' or base == 'bytes' or base == 'hash': if sub: bytes = ethereum_utils.int_to_32bytearray(int(data, 16)) while bytes and bytes[-1] == 0: bytes.pop() if bytes: return ''.join(chr(b) for b in bytes) else: num_bytes = int(data[64 + 2:128 + 2], 16) bytes_as_hex = data[2 + 128:2 + 128 + (2 * num_bytes)] return ethereum_utils.decode_hex(bytes_as_hex) elif base == 'uint': return int(data, 16) elif base == 'int': o = int(data, 16) return (o - 2**int(sub)) if o >= 2**(int(sub) - 1) else o elif base == 'ureal': raise NotImplementedError('havent gotten to this') high, low = [int(x) for x in sub.split('x')] # return big_endian_to_int(data) * 1.0 / 2 ** low elif base == 'real': raise NotImplementedError('havent gotten to this') high, low = [int(x) for x in sub.split('x')] # return (big_endian_to_int(data) * 1.0 / 2 ** low) % 2 ** high elif base == 'bool': return bool(int(data, 16)) else: raise ValueError("Unknown base: `{0}`".format(base))
def createOrder(orderHash, key=tester.k0): key = normalize_key(key) v, r, s = ecsign(sha3("\x19Ethereum Signed Message:\n32" + orderHash), key) return v, zpad(bytearray_to_bytestr(int_to_32bytearray(r)), 32), zpad(bytearray_to_bytestr(int_to_32bytearray(s)), 32)
import serpent from ethereum.tools import tester from ethereum import utils serpent_code=''' def sha3check(choice, nonce): return(sha3([msg.sender, choice, nonce], items=3)) ''' s = tester.Chain() c = s.contract(serpent_code, language='serpent') choice1 = 1048576 nonce1 = 3628800 print('the sha3 result computed by serpent:') print(c.sha3check(choice1, nonce1, sender=tester.k0)) ch1 = bytearray(utils.int_to_32bytearray(choice1)) no1 = bytearray(utils.int_to_32bytearray(nonce1)) tohash = bytearray().join([utils.zpad(tester.a0, 32), ch1, no1]) print('the sha3 result computed by pyethereum') print(utils.coerce_to_int(utils.sha3(bytes(tohash))))