//uint8 a=2;
//transaction cost:89426 execution cost:34630
//uint64 a = 2;
//transaction cost:89650 execution cost:34630
这是因为以太坊虚拟机(EVM)的字长为256位/32字节,每个操作都是基于这些基本单位的。如果你的数据比256位小,那么需要进一步的操作来将256位缩小到8位,因此你会看到增加的成本
具体看字节码:
//uint8 a = 2;
// PUSH1 0x80:将字节码中的0x80(十进制128)推送到栈顶。
// PUSH1 0x40:将字节码中的0x40(十进制64)推送到栈顶。
// MSTORE:将栈顶值存储到栈顶位置指定的内存位置。
// PUSH1 0x2:将字节码中的0x2(十进制2)推送到栈顶。
// PUSH0:将字节码中的0x0(十进制0)推送到栈顶。
// DUP1:复制栈顶元素。
// PUSH2 0x100:将字节码中的0x100(十进制256)推送到栈顶。
// EXP:将栈顶两个元素相乘,并将结果推送到栈顶。
// DUP2:复制第二个栈顶元素。
// SLOAD:从存储中加载数据到栈顶。
// DUP2:复制第二个栈顶元素。
// PUSH1 0xFF:将字节码中的0xFF(十进制255)推送到栈顶。
// MUL:将栈顶两个元素相乘。
// NOT:将栈顶元素取反。
// AND:对栈顶两个元素进行按位与操作。
// SWAP1:交换栈顶两个元素。
// DUP4:复制第四个栈顶元素。
// PUSH1 0xFF:将字节码中的0xFF(十进制255)推送到栈顶。
// AND:对栈顶两个元素进行按位与操作。
// MUL:将栈顶两个元素相乘。
// OR:对栈顶两个元素进行按位或操作。
// SWAP1:交换栈顶两个元素。
// SSTORE:将栈顶元素存储到存储位置。
// POP:从栈中弹出元素。
// CALLVALUE:将调用值(发送的以太币数量)压入栈顶。
// DUP1:复制栈顶元素。
// ISZERO:判断栈顶元素是否为0。
// PUSH1 0x28:将字节码中的0x28(十进制40)推送到栈顶。
// JUMPI:如果栈顶元素为零,则根据给定的偏移量跳转。
// PUSH0:将字节码中的0x0(十进制0)推送到栈顶。
// DUP1:复制栈顶元素。
// REVERT:回滚到先前的状态并停止执行合约。
// JUMPDEST:跳转目标。
// POP:从栈中弹出元素。
// PUSH1 0x3E:将字节码中的0x3E(十进制62)推送到栈顶。
// DUP1:复制栈顶元素。
// PUSH1 0x34:将字节码中的0x34(十进制52)推送到栈顶。
// PUSH0:将字节码中的0x0(十进制0)推送到栈顶。
// CODECOPY:将代码复制到内存中的指定位置。
// PUSH0:将字节码中的0x0(十进制0)推送到栈顶。
// RETURN:停止执行合约并将结果返回给调用者。
// INVALID:无效操作码,终止合约执行。
// PUSH1 0x80:将字节码中的0x80(十进制128)推送到栈顶。
// PUSH1 0x40:将字节码中的0x40(十进制64)推送到栈顶。
// MSTORE:将栈顶值存储到栈顶位置指定的内存位置。
// PUSH0:将字节码中的0x0(十进制0)推送到栈顶。
// DUP1:复制栈顶元素。
// REVERT:回滚到先前的状态并停止执行合约。
// INVALID:无效操作码,终止合约执行。
// LOG2:将栈顶两个元素的对数值推送到栈顶。
// PUSH5 0x6970667358:将字节码中的0x6970667358推送到栈顶。
// PUSH1 0x22:将字节码中的0x22(十进制34)推送到栈顶。
// SLT:如果第二个栈顶元素小于栈顶元素,则将1推送到栈顶;否则将0推送到栈顶。
// KECCAK256:将栈顶元素进行Keccak-256哈希运算。
// INVALID:无效操作码,终止合约执行。
// PUSH1 0x25:将字节码中的0x25(十进制37)推送到栈顶。
// MSTORE8:将栈顶元素的低8位存储到栈顶位置指定的内存位置。
// PUSH17 0x23C37BB780D303F1FB9B8C54DF281B06AC:将字节码中的0x23C37BB780D303F1FB9B8C54DF281B06AC推送到栈顶。
// CODECOPY:将代码复制到内存中的指定位置。
// MOD:计算栈顶两个元素相除的余数,并将结果推送到栈顶。
// PUSH2 0x9F42:将字节码中的0x9F42(十进制40770)推送到栈顶。
// PUSH1 0x23:将字节码中的0x23(十进制35)推送到栈顶。
// PUSH1 0x22:将字节码中的0x22(十进制34)推送到栈顶。
// CDIV:计算栈顶两个元素相除的商,并将结果推送到栈顶。
// PUSH5 0x736F6C6343:将字节码中的0x736F6C6343推送到栈顶。
// STOP:停止执行合约。
// ADDMOD:计算栈顶三个元素相加然后取模的结果,并将结果推送到栈顶。
// EQ:如果栈顶两个元素相等,则将1推送到栈顶;否则将0推送到栈顶。
// STOP:停止执行合约。
// CALLER:将调用合约的地址(调用者地址)推送到栈顶。
//uint256 b = 2;
// PUSH1 0x80:将十进制值128(0x80)推送到栈顶。
// PUSH1 0x40:将十进制值64(0x40)推送到栈顶。
// MSTORE:将栈顶的数值存储到栈顶位置指定的内存位置。
// PUSH1 0x2:将十进制值2(0x2)推送到栈顶。
// PUSH0:将十进制值0(0x0)推送到栈顶。
// SSTORE:将栈顶的数值存储到存储位置。
// CALLVALUE:将调用合约时发送的以太币数量推送到栈顶。
// DUP1:复制栈顶元素。
// ISZERO:判断栈顶元素是否为零。
// PUSH1 0x12:将十进制值18(0x12)推送到栈顶。
// JUMPI:如果栈顶元素为零,则根据给定的偏移量跳转。
// PUSH0:将十进制值0(0x0)推送到栈顶。
// DUP1:复制栈顶元素。
// REVERT:回滚到先前的状态并停止执行合约。
// JUMPDEST:跳转目标。
// POP:从栈中弹出元素。
// PUSH1 0x3E:将十进制值62(0x3E)推送到栈顶。
// DUP1:复制栈顶元素。
// PUSH1 0x1E:将十进制值30(0x1E)推送到栈顶。
// PUSH0:将十进制值0(0x0)推送到栈顶。
// CODECOPY:将代码复制到内存中的指定位置。
// PUSH0:将十进制值0(0x0)推送到栈顶。
// RETURN:停止执行合约并将结果返回给调用者。
// INVALID:无效操作码,终止合约执行。
// PUSH1 0x80:将十进制值128(0x80)推送到栈顶。
// PUSH1 0x40:将十进制值64(0x40)推送到栈顶。
// MSTORE:将栈顶的数值存储到栈顶位置指定的内存位置。
// PUSH0:将十进制值0(0x0)推送到栈顶。
// DUP1:复制栈顶元素。
// REVERT:回滚到先前的状态并停止执行合约。
// INVALID:无效操作码,终止合约执行。
// LOG2:将栈顶两个元素的对数值推送到栈顶。
// PUSH5 0x6970667358:将十进制值711931355112(0x6970667358)推送到栈顶。
// PUSH1 0x22:将十进制值34(0x22)推送到栈顶。
// SLT:如果第二个栈顶元素小于栈顶元素,则将1推送到栈顶;否则将0推送到栈顶。
// KECCAK256:将栈顶元素进行Keccak-256哈希运算。
// EXP:将栈顶两个元素相乘,并将结果推送到栈顶。
// PUSH1 0xFC:将十进制值252(0xFC)推送到栈顶。
// PUSH1 0xBB:将十进制值187(0xBB)推送到栈顶。
// PUSH1 0x2F:将十进制值47(0x2F)推送到栈顶。
// SWAP7:交换栈顶元素和第七个栈元素的位置。
// MSIZE:将当前内存大小推送到栈顶。
// MSTORE:将栈顶的数值存储到栈顶位置指定的内存位置。
// 0xB5:无效操作码。
// 0xC7:无效操作码。
// RETURNDATASIZE:将返回数据的大小推送到栈顶。
// 0xC6:无效操作码。
// PUSH18 0x7B124BD490A4EBA0F5F94C4192873ECC38C6:将十六进制值0x7B124BD490A4EBA0F5F94C4192873ECC38C6推送到栈顶。
// SUB:将栈顶两个元素相减,并将结果推送到栈顶。
// JUMPI:如果栈顶元素为零,则根据给定的偏移量跳转。
// PUSH5 0x736F6C6343:将十进制值79354843331(0x736F6C6343)推送到栈顶。
// STOP:停止执行合约。
// ADDMOD:将栈顶两个元素相加,然后对第三个栈顶元素取模,并将结果推送到栈顶。
// EQ:如果第二个栈顶元素等于栈顶元素,则将1推送到栈顶;否则将0推送到栈顶。
// STOP:停止执行合约。
// CALLER:将调用合约的地址推送到栈顶。
当时如果有两个变量就不同了:
// uint128 internal a = 1640784985;
// uint128 internal b = 1640784985;
//transaction cost:91224 execution cost:34946
// uint256 internal a = 1640784985;
// uint256 internal b = 1640784985;
//transaction cost:111307 execution cost:56675
留个疑问?有知道的吗,哈哈