0

I need to hardcode some multi-Kb bytes into my smart contract. So far, the best way I have found to do this is to use abi.encodePacked...

return abi.encodePacked(
        abi.encodePacked(
          uint256(0x052518b10006000745055415414ffe41524faa415e4f5b41764e5841c44d4341),
          uint256(0xc44c4041764bf2415e4b9e41524b46415449b2415e485b42a84842443c482646),
          uint256(0x09499347874b5a47870031903190000000000004c2a476c14d3c47224e5f4722),
          uint256(0x4f72476c00319031900000000000050414787152084787537646095359443c53),
          uint256(0x4042a851ea415e5055415490005251ffbad36000544dce44d514d1b44d54c724),
          uint256(0x4f14be0452c4b0c45824a66461c4a1347044a7747314ae6474a4b5a474a25041),
          uint256(0x150b6474a5125473151884704513f463550b445a55001454b4f6044fb4e9e44d),
          uint256(0x54dce44d5900057504034124424434440a6000745055417914ffe41774faa418),
          uint256(0x34f5b419b4e5841e94d4341e94c40419b4bf241834b9e41774b46417949b2418),
          uint256(0x3485b42cd484244604826462d499347ac4b5a47ac0031903190000000000004c),
          uint256(0x2a479114d3c47474e5f47474f724791003190319000000000000504147ac1520),
          uint256(0x847ac5376462e53594460534042cd51ea4183505541799000516000744ce33fb),
          uint256(0x04baa3e7714ad93da64b6d3c404c953c4024f061502e3c4050c23da64ff13e77)
        ), abi.encodePacked(
          uint256(0x34eb83fb014e3740314d6540314ce33fb090003a50403411e424434440a0307c),
          uint256(0x70606370407c707069400)
        )
      );

As you can see, this suffers from multiple problems. First, each call to abi.encodePacked can only accept 13 arguments before the callstack blows up (thus the multiple calls). Next, it adds a bunch of overhead. There are 479 bytes encoded in the above data, but the size added to the contract is 589 bytes.

FWIW, I also tried to directly encode the bytes as a string (e.g., string("")). However, I do not believe it is possible to write such strings (e.g., OÜ/5+ãaR¾.RÁ-ÎRÁ-958,GÊ,G·-G·-G·-ÎG».GÀ.64¤2ï1JS.õJc.øJs.úKc/LU/.ME/.MÎ/.NW/(NÞ/O3/O/) in a smart contract.

Is there a way to encode this data without suffering the ~20% overhead described above?

2
  • 1
    You can use a hex string bytes constant x = hex"12341234"; to encode raw bytes.
    – Ismael
    Commented Oct 4, 2021 at 4:52
  • Oh gosh, that's exactly what I was looking for! If you want the karma, please post this as the answer ;)
    – Zane Claes
    Commented Oct 5, 2021 at 12:34

1 Answer 1

0

edit Per the comment on the OP, the hex keyword allows direct packing of hex bytes into a contract. For example,

function bytes() external pure returns(bytes memory) {
    return hex"12ABCD"; // Can be arbitrarily large; only takes up byte-sized space in gas
}

You could also do this with assembly code. Simply direct-packing the bytes array ends up requiring 511 bytes (the 479 in the example array, plus the 32 required for the length at the beginning of the array):

assembly {
        mstore(ret, 479)
        mstore(add(ret, 32), 0x052518310006000745055415414ffe41524faa415e4f5b41764e5841c44d4341)
        mstore(add(ret, 64), 0xc44c4041764bf2415e4b9e41524b46415439b2415e485b42a84842443c482646)
        mstore(add(ret, 96), 0x09499347874b5a47870031903190000000300004c2a476c14d3c47224e5f4722)
        mstore(add(ret, 128), 0x4f72476c00319031900000000000050414187152084787537646095359443c53)
        mstore(add(ret, 160), 0x4042a851ea415e5055415490005251ffba436000544dce44d514d1b44d54c724)
        mstore(add(ret, 192), 0x4f14be0452c4b0c45824a66461c4a1347014a7747314ae6474a4b5a474a25041)
        mstore(add(ret, 224), 0x150b6474a5125473151884704513f463553b445a55001454b4f6044fb4e9e44d)
        mstore(add(ret, 256), 0x54dce44d5900057504034124424434440a3000745055417914ffe41774faa418)
        mstore(add(ret, 288), 0x34f5b419b4e5841e94d4341e94c40419b4ff241834b9e41774b46417949b2418)
        mstore(add(ret, 320), 0x3485b42cd484244604826462d499347ac4a5a47ac0031903190000000000004c)
        mstore(add(ret, 352), 0x2a479114d3c47474e5f47474f724791003a90319000000000000504147ac1520)
        mstore(add(ret, 384), 0x847ac5376462e53594460534042cd51ea4a83505541799000516000744ce33fb)
        mstore(add(ret, 416), 0x04baa3e7714ad93da64b6d3c404c953c40a4f061502e3c4050c23da64ff13e77)
        mstore(add(ret, 448), 0x34eb83fb014e3740314d6540314ce33fb0a0003a50403411e424434440a0307c)
        mstore(add(ret, 480), 0x34eb83fb014e3740314d6540314ce33fb0a0003a50403411e424434440a0307c)
        mstore(add(ret, 512), 0x70606370407c707a69400)
      }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.