ETH Price: $3,475.88 (-1.19%)
Gas: 3 Gwei

Contract

0xB9Ad592B621FDa46f424d010104EA5567E20874a
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040150016972022-06-21 9:52:27762 days ago1655805147IN
 Create: EtherealStatesDNA
0 ETH0.0166090625.78515112

Advanced mode:
Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
EtherealStatesDNA

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license
File 1 of 1 : EtherealStatesDNA.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

/// @title EtherealStatesDNA
/// @author Artist: GenuineHumanArt (https://twitter.com/GenuineHumanArt)
/// @author Developer: dievardump (https://twitter.com/dievardump, [email protected])
/// @notice Generates DNA for EtherealStates NFTs
///         A big thank you to cxkoda (https://twitter.com/cxkoda) who helped me with the bit manipulation
///         & assembly and saved quite some gas.
contract EtherealStatesDNA {
    error WrongDistributionForLayer(uint256 layer, uint256 acc);

    function checkLayersValidity() public pure {
        unchecked {
            bytes memory layer;
            uint256 acc;
            uint256 i;
            for (uint256 j; j < 20; j++) {
                layer = getLayer(j);
                acc = 0;
                assembly {
                    for {
                        let current := add(layer, 0x20)
                        let length := mload(layer)
                    } lt(i, length) {
                        current := add(current, 2)
                        i := add(i, 2)
                    } {
                        acc := add(acc, sar(240, mload(current)))
                    }
                    i := 0
                }

                if (acc != 10000) {
                    revert WrongDistributionForLayer(j, acc);
                }
            }
        }
    }

    function generate(uint256 seed, bool includeHolderTraits)
        public
        pure
        returns (bytes32)
    {
        uint256 dna;
        uint256 random;

        unchecked {
            for (uint256 i; i < 20; i++) {
                // keccak the seed, very simple prng
                // we do it on each call, because even if Holders layer is not shown we want to be sure
                // the layers after stay the same with or without it
                seed = uint256(keccak256(abi.encode(seed)));

                // next random number
                random = seed % 10000;

                // push 8 null bits on the right side
                dna <<= 8;

                // done here and not in consumer, because getLayer(i) and pickOne are costly operations.
                // this way we save the gas when the trait is not included
                if (i != 12 || includeHolderTraits) {
                    // set the last 8 bits to the index of the asset in the layer
                    dna |= _pickOne(getLayer(i), random);
                }
            }

            // add 96 null bits right
            dna <<= 96;
        }
        return bytes32(dna);
    }

    function _pickOne(bytes memory layer, uint256 chance)
        public
        pure
        returns (uint256)
    {
        unchecked {
            uint256 i;
            assembly {
                for {
                    let current := add(layer, 0x20)
                    let acc
                } 1 {
                    // add 2 bytes to current position
                    current := add(current, 2)
                    i := add(i, 2)
                } {
                    // add the value of the 2 first bytes of current in acc
                    acc := add(acc, sar(240, mload(current)))
                    // if chance < acc
                    if lt(chance, acc) {
                        break
                    }
                }
                i := sar(1, i)
            }
            return i;
        }
    }

    // this is pretty dirty but this saves quite some gas
    // 1) putting the layers in storage would be very expensive when deploying & when reading storage
    // 2) using arrays of uint for that many assets (512), is too big for a contract
    // After tests, this seems to be a good working compromise
    function getLayer(uint256 which) public pure returns (bytes memory layer) {
        if (which == 0)
            layer = hex'01900190017c017c019001900006015e01900040017c00be0190000a0190015e017c017c0190015e001000680190017c0190017c00140020017c0087017c017c00df015e';
        else if (which == 1)
            layer = hex'012e0132007c00a0005e000a012c01e701e7000c000800b4006401e700a201e701e701e701e701bb01e701e7000e01e701b7000c01b701bb007c0130000e01e701e700a6';
        else if (which == 2)
            layer = hex'01b8019001b801b801a4011801cc01cc01cc0168001401cc01cc01b801cc01b801cc01b801b801b801b801cc01a401cc';
        else if (which == 3)
            layer = hex'004b003602080208020802080208004b00780208009102080110020802080208020801ae020801ae0208004f020802080208';
        else if (which == 4)
            layer = hex'007d004002080208020802080208004b020800a502080129020802080208020801c2020801c202080036020802080208';
        else if (which == 5)
            layer = hex'02260226021202120226021200d2012c022600aa02260096004002120212010400780212005602260212021202260226';
        else if (which == 6)
            layer = hex'01c201c200320064017201c201c20172001901c2017201720096017200960172003201c201c2017201c20064001901c2017201720064017201c201c2009601c2';
        else if (which == 7)
            layer = hex'00a01d4c005500780055009f00c700c7000700a000c700c7009f000500780055005500780005001e00c70078';
        else if (which == 8)
            layer = hex'01a901f401b301b301f401b301b301f401f4010e01f401f401b301f401b301f401a901f4005a01f40096001e01f401f4';
        else if (which == 9)
            layer = hex'020801b301b30208020801b300640208003c020800a001b301e501e501b30208015e020801b300c802080208015e0208';
        else if (which == 10)
            layer = hex'01e001fe019a019a01fe01e001fe01e0019a003201e001fe00960069004b01fe01fe01fe01fe01e001e001fe01fe019a';
        else if (which == 11)
            layer = hex'01f401f401f401f4012c01f40194019401e0001401e001f401f401e0000a019401e001e0019401f401f4019400fa01f4';
        else if (which == 12)
            layer = hex'0000032f032f032f032f032f032f01e00154032f01e00226032f032f032f';
        else if (which == 13)
            layer = hex'00780205020502050205008c01e002050205020501e0020500a000c001e001e00036020501e001e0020500fa02050205';
        else if (which == 14)
            layer = hex'020800be01e0020801e001fe01fe01e000fa003c01e0020800640208008c020801e00208020801e002080208020800a0';
        else if (which == 15)
            layer = hex'0194007801e0019401ea01ea01e00194000a019401ea01ea01ea01ea012c01e000fa01ea01ea01e001e001ea01ea0194';
        else if (which == 16)
            layer = hex'003201c2014301c201c2000a0143000f01c20143014301c200a000a00007005001c2003c00a001c2014301c201c201c201c201c201c201c2014301c201c200a0';
        else if (which == 17)
            layer = hex'00a00143005001a401a400f001a4006401a401a401a401a40143014301a4000a01a400f001a401a401a401a401a401a4014a01a400f000a0003c01430143002d';
        else if (which == 18)
            layer = hex'0143005001a401a401a4014301a40082002d01a4000a01a401a400f001a401a401a400a001a4004601a400a001a401430143014301a4017c00f001a4014a00f0';
        else if (which == 19)
            layer = hex'000a000a000a000a000a000a000a000a268e000a000a000a000a000a';
    }
}

Settings
{
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs",
    "useLiteralContent": true
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": [],
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"layer","type":"uint256"},{"internalType":"uint256","name":"acc","type":"uint256"}],"name":"WrongDistributionForLayer","type":"error"},{"inputs":[{"internalType":"bytes","name":"layer","type":"bytes"},{"internalType":"uint256","name":"chance","type":"uint256"}],"name":"_pickOne","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"checkLayersValidity","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"seed","type":"uint256"},{"internalType":"bool","name":"includeHolderTraits","type":"bool"}],"name":"generate","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"which","type":"uint256"}],"name":"getLayer","outputs":[{"internalType":"bytes","name":"layer","type":"bytes"}],"stateMutability":"pure","type":"function"}]

608060405234801561001057600080fd5b50610ab7806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c806311527aa2146100515780635de2cec51461005b578063ef5e9f8d14610081578063f781e3ae14610094575b600080fd5b6100596100b4565b005b61006e61006936600461054d565b610141565b6040519081526020015b60405180910390f35b61006e61008f366004610598565b6101c2565b6100a76100a236600461064d565b6101fc565b6040516100789190610666565b606060008060005b601481101561013b576100ce816101fc565b9350600092506020840184515b808410156100fd57815160f01d850194506002820191506002840193506100db565b50506000915082612710146101335760405163786fd38f60e11b8152600481018290526024810184905260440160405180910390fd5b6001016100bc565b50505050565b6000806000805b60148110156101b65760408051602081018890520160408051601f198184030181529190528051602090910120955061271086069150600883901b925080600c1415806101925750845b156101ae576101a96101a3826101fc565b836101c2565b831792505b600101610148565b505060601b9392505050565b6000806020840160005b815160f01d01808510156101df576101f0565b6002820191506002830192506101cc565b505060011d9392505050565b606081610222576040518060800160405280604481526020016107f86044913992915050565b816001141561024a5760405180608001604052806044815260200161093e6044913992915050565b8160021415610272576040518060600160405280603081526020016106bc6030913992915050565b816003141561029a5760405180606001604052806032815260200161083c6032913992915050565b81600414156102c2576040518060600160405280603081526020016109e26030913992915050565b81600514156102ea57604051806060016040528060308152602001610a526030913992915050565b8160061415610312576040518060600160405280604081526020016108fe6040913992915050565b816007141561033a576040518060600160405280602c81526020016106ec602c913992915050565b8160081415610362576040518060600160405280603081526020016109b26030913992915050565b816009141561038a576040518060600160405280603081526020016108ce6030913992915050565b81600a14156103b25760405180606001604052806030815260200161089e6030913992915050565b81600b14156103da576040518060600160405280603081526020016107186030913992915050565b81600c141561041a57505060408051808201909152601e81527d032f032f032f032f032f032f01e00154032f01e00226032f032f032f0000602082015290565b81600d1415610442576040518060600160405280603081526020016107486030913992915050565b81600e141561046a5760405180606001604052806030815260200161086e6030913992915050565b81600f1415610492576040518060600160405280603081526020016109826030913992915050565b81601014156104ba576040518060600160405280604081526020016107b86040913992915050565b81601114156104e2576040518060600160405280604081526020016107786040913992915050565b816012141561050a57604051806060016040528060408152602001610a126040913992915050565b8160131415610548575060408051808201909152601c81527e0a000a000a000a000a000a000a000a268e000a000a000a000a000a0000000060208201525b919050565b6000806040838503121561056057600080fd5b823591506020830135801515811461057757600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156105ab57600080fd5b823567ffffffffffffffff808211156105c357600080fd5b818501915085601f8301126105d757600080fd5b8135818111156105e9576105e9610582565b604051601f8201601f19908116603f0116810190838211818310171561061157610611610582565b8160405282815288602084870101111561062a57600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b60006020828403121561065f57600080fd5b5035919050565b600060208083528351808285015260005b8181101561069357858101830151858201604001528201610677565b818111156106a5576000604083870101525b50601f01601f191692909201604001939250505056fe01b8019001b801b801a4011801cc01cc01cc0168001401cc01cc01b801cc01b801cc01b801b801b801b801cc01a401cc00a01d4c005500780055009f00c700c7000700a000c700c7009f000500780055005500780005001e00c7007801f401f401f401f4012c01f40194019401e0001401e001f401f401e0000a019401e001e0019401f401f4019400fa01f400780205020502050205008c01e002050205020501e0020500a000c001e001e00036020501e001e0020500fa0205020500a00143005001a401a400f001a4006401a401a401a401a40143014301a4000a01a400f001a401a401a401a401a401a4014a01a400f000a0003c01430143002d003201c2014301c201c2000a0143000f01c20143014301c200a000a00007005001c2003c00a001c2014301c201c201c201c201c201c201c2014301c201c200a001900190017c017c019001900006015e01900040017c00be0190000a0190015e017c017c0190015e001000680190017c0190017c00140020017c0087017c017c00df015e004b003602080208020802080208004b00780208009102080110020802080208020801ae020801ae0208004f020802080208020800be01e0020801e001fe01fe01e000fa003c01e0020800640208008c020801e00208020801e002080208020800a001e001fe019a019a01fe01e001fe01e0019a003201e001fe00960069004b01fe01fe01fe01fe01e001e001fe01fe019a020801b301b30208020801b300640208003c020800a001b301e501e501b30208015e020801b300c802080208015e020801c201c200320064017201c201c20172001901c2017201720096017200960172003201c201c2017201c20064001901c2017201720064017201c201c2009601c2012e0132007c00a0005e000a012c01e701e7000c000800b4006401e700a201e701e701e701e701bb01e701e7000e01e701b7000c01b701bb007c0130000e01e701e700a60194007801e0019401ea01ea01e00194000a019401ea01ea01ea01ea012c01e000fa01ea01ea01e001e001ea01ea019401a901f401b301b301f401b301b301f401f4010e01f401f401b301f401b301f401a901f4005a01f40096001e01f401f4007d004002080208020802080208004b020800a502080129020802080208020801c2020801c2020800360208020802080143005001a401a401a4014301a40082002d01a4000a01a401a400f001a401a401a400a001a4004601a400a001a401430143014301a4017c00f001a4014a00f002260226021202120226021200d2012c022600aa02260096004002120212010400780212005602260212021202260226a2646970667358221220ab58b34015bf87c004d7733dc13f5f511358b2aee8678c2729235482630ae4b064736f6c634300080c0033

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806311527aa2146100515780635de2cec51461005b578063ef5e9f8d14610081578063f781e3ae14610094575b600080fd5b6100596100b4565b005b61006e61006936600461054d565b610141565b6040519081526020015b60405180910390f35b61006e61008f366004610598565b6101c2565b6100a76100a236600461064d565b6101fc565b6040516100789190610666565b606060008060005b601481101561013b576100ce816101fc565b9350600092506020840184515b808410156100fd57815160f01d850194506002820191506002840193506100db565b50506000915082612710146101335760405163786fd38f60e11b8152600481018290526024810184905260440160405180910390fd5b6001016100bc565b50505050565b6000806000805b60148110156101b65760408051602081018890520160408051601f198184030181529190528051602090910120955061271086069150600883901b925080600c1415806101925750845b156101ae576101a96101a3826101fc565b836101c2565b831792505b600101610148565b505060601b9392505050565b6000806020840160005b815160f01d01808510156101df576101f0565b6002820191506002830192506101cc565b505060011d9392505050565b606081610222576040518060800160405280604481526020016107f86044913992915050565b816001141561024a5760405180608001604052806044815260200161093e6044913992915050565b8160021415610272576040518060600160405280603081526020016106bc6030913992915050565b816003141561029a5760405180606001604052806032815260200161083c6032913992915050565b81600414156102c2576040518060600160405280603081526020016109e26030913992915050565b81600514156102ea57604051806060016040528060308152602001610a526030913992915050565b8160061415610312576040518060600160405280604081526020016108fe6040913992915050565b816007141561033a576040518060600160405280602c81526020016106ec602c913992915050565b8160081415610362576040518060600160405280603081526020016109b26030913992915050565b816009141561038a576040518060600160405280603081526020016108ce6030913992915050565b81600a14156103b25760405180606001604052806030815260200161089e6030913992915050565b81600b14156103da576040518060600160405280603081526020016107186030913992915050565b81600c141561041a57505060408051808201909152601e81527d032f032f032f032f032f032f01e00154032f01e00226032f032f032f0000602082015290565b81600d1415610442576040518060600160405280603081526020016107486030913992915050565b81600e141561046a5760405180606001604052806030815260200161086e6030913992915050565b81600f1415610492576040518060600160405280603081526020016109826030913992915050565b81601014156104ba576040518060600160405280604081526020016107b86040913992915050565b81601114156104e2576040518060600160405280604081526020016107786040913992915050565b816012141561050a57604051806060016040528060408152602001610a126040913992915050565b8160131415610548575060408051808201909152601c81527e0a000a000a000a000a000a000a000a268e000a000a000a000a000a0000000060208201525b919050565b6000806040838503121561056057600080fd5b823591506020830135801515811461057757600080fd5b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600080604083850312156105ab57600080fd5b823567ffffffffffffffff808211156105c357600080fd5b818501915085601f8301126105d757600080fd5b8135818111156105e9576105e9610582565b604051601f8201601f19908116603f0116810190838211818310171561061157610611610582565b8160405282815288602084870101111561062a57600080fd5b826020860160208301376000602093820184015298969091013596505050505050565b60006020828403121561065f57600080fd5b5035919050565b600060208083528351808285015260005b8181101561069357858101830151858201604001528201610677565b818111156106a5576000604083870101525b50601f01601f191692909201604001939250505056fe01b8019001b801b801a4011801cc01cc01cc0168001401cc01cc01b801cc01b801cc01b801b801b801b801cc01a401cc00a01d4c005500780055009f00c700c7000700a000c700c7009f000500780055005500780005001e00c7007801f401f401f401f4012c01f40194019401e0001401e001f401f401e0000a019401e001e0019401f401f4019400fa01f400780205020502050205008c01e002050205020501e0020500a000c001e001e00036020501e001e0020500fa0205020500a00143005001a401a400f001a4006401a401a401a401a40143014301a4000a01a400f001a401a401a401a401a401a4014a01a400f000a0003c01430143002d003201c2014301c201c2000a0143000f01c20143014301c200a000a00007005001c2003c00a001c2014301c201c201c201c201c201c201c2014301c201c200a001900190017c017c019001900006015e01900040017c00be0190000a0190015e017c017c0190015e001000680190017c0190017c00140020017c0087017c017c00df015e004b003602080208020802080208004b00780208009102080110020802080208020801ae020801ae0208004f020802080208020800be01e0020801e001fe01fe01e000fa003c01e0020800640208008c020801e00208020801e002080208020800a001e001fe019a019a01fe01e001fe01e0019a003201e001fe00960069004b01fe01fe01fe01fe01e001e001fe01fe019a020801b301b30208020801b300640208003c020800a001b301e501e501b30208015e020801b300c802080208015e020801c201c200320064017201c201c20172001901c2017201720096017200960172003201c201c2017201c20064001901c2017201720064017201c201c2009601c2012e0132007c00a0005e000a012c01e701e7000c000800b4006401e700a201e701e701e701e701bb01e701e7000e01e701b7000c01b701bb007c0130000e01e701e700a60194007801e0019401ea01ea01e00194000a019401ea01ea01ea01ea012c01e000fa01ea01ea01e001e001ea01ea019401a901f401b301b301f401b301b301f401f4010e01f401f401b301f401b301f401a901f4005a01f40096001e01f401f4007d004002080208020802080208004b020800a502080129020802080208020801c2020801c2020800360208020802080143005001a401a401a4014301a40082002d01a4000a01a401a400f001a401a401a400a001a4004601a400a001a401430143014301a4017c00f001a4014a00f002260226021202120226021200d2012c022600aa02260096004002120212010400780212005602260212021202260226a2646970667358221220ab58b34015bf87c004d7733dc13f5f511358b2aee8678c2729235482630ae4b064736f6c634300080c0033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.