def length_prefix(length, offset): """Construct the prefix to lists or strings denoting their length. :param length: the length of the item in bytes :param offset: ``0x80`` when encoding raw bytes, ``0xc0`` when encoding a list """ if length < 56: return chr(offset + length) else: length_string = int_to_big_endian(length) return chr(offset + 56 - 1 + len(length_string)) + length_string
def proc_modexp(ext, msg): if not ext.post_metropolis_hardfork(): return 1, msg.gas, [] print('modexp proc', msg.gas) baselen = msg.data.extract32(0) explen = msg.data.extract32(32) modlen = msg.data.extract32(64) first_exp_bytes = msg.data.extract32( 96 + baselen) >> (8 * max(32 - explen, 0)) bitlength = -1 while first_exp_bytes: bitlength += 1 first_exp_bytes >>= 1 adjusted_explen = max(bitlength, 0) + 8 * max(explen - 32, 0) gas_cost = (mult_complexity(max(modlen, baselen)) * max(adjusted_explen, 1)) // opcodes.GMODEXPQUADDIVISOR print(baselen, explen, modlen, 'expected gas cost', gas_cost) if msg.gas < gas_cost: return 0, 0, [] if baselen == 0: return 1, msg.gas - gas_cost, [0] * modlen if modlen == 0: return 1, msg.gas - gas_cost, [] base = bytearray(baselen) msg.data.extract_copy(base, 0, 96, baselen) exp = bytearray(explen) msg.data.extract_copy(exp, 0, 96 + baselen, explen) mod = bytearray(modlen) msg.data.extract_copy(mod, 0, 96 + baselen + explen, modlen) if utils.big_endian_to_int(mod) == 0: return 1, msg.gas - gas_cost, [0] * modlen o = pow( utils.big_endian_to_int(base), utils.big_endian_to_int(exp), utils.big_endian_to_int(mod)) return 1, msg.gas - \ gas_cost, [ safe_ord(x) for x in utils.zpad( utils.int_to_big_endian(o), modlen)]
def b64(int_bloom): "returns b256" return utils.zpad(utils.int_to_big_endian(int_bloom), 256)