{"_id":"@beskay/erc721b","_rev":"5-6b0130f264257ed25d2fe3ad5e0ed7a2","name":"@beskay/erc721b","dist-tags":{"latest":"1.0.4"},"versions":{"1.0.0":{"name":"@beskay/erc721b","version":"1.0.0","description":"Updated, minimalist and gas efficient version of OpenZeppelins ERC721 contract","scripts":{"node":"hardhat node","test":"hardhat test","test:gas":"REPORT_GAS=true npx hardhat test"},"devDependencies":{"@nomiclabs/hardhat-ethers":"^2.0.4","@nomiclabs/hardhat-waffle":"^2.0.2","chai":"^4.3.6","ethereum-waffle":"^3.4.0","ethers":"^5.5.4","hardhat":"^2.8.3","hardhat-gas-reporter":"^1.0.7","prettier":"^2.5.1","prettier-plugin-solidity":"^1.0.0-beta.19"},"dependencies":{"@openzeppelin/contracts":"^4.4.2"},"author":{"name":"beskay"},"license":"GPL-3.0-or-later","repository":{"type":"git","url":"git+https://github.com/beskay/ERC721B.git"},"gitHead":"a37b559b89743f33d88b26c36b01f1bab9669eb0","bugs":{"url":"https://github.com/beskay/ERC721B/issues"},"homepage":"https://github.com/beskay/ERC721B#readme","_id":"@beskay/erc721b@1.0.0","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-ssmcH+qky6uetr6OQN7f8kUJnXUrnlie1ULxnlGUtTQqugMHTjZ7/OiK8zov+By+kkdLPBf6ltp5+sVLxLKCMQ==","shasum":"311cd4dd27f248462435cc66016640169be6c0b6","tarball":"https://registry.npmjs.org/@beskay/erc721b/-/erc721b-1.0.0.tgz","fileCount":4,"unpackedSize":55440,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiBlTPCRA9TVsSAnZWagAAq6YP/1TxGBd0CRilhLJmEUba\nD7F+pmhXRqzVWrSdzCEa/932pw5j4u92x5TvTvPtVLqZwxmlxi/JCzTy7F4G\nryRKZ+iltcqg/aV85s1vhDDsXgiNEg/we4C3Gk4hBby5qUT5d2yQbl9zHfdq\nNHrgFWnUuruQgGCp0ojtXo+Y3rS+OcdEC4e6YdVqRC/2H3spEzOHVfXazwLE\nEnrLAsZ3BiNhinVF5prYSVNKW8emLuI5tX0rU6lK0nQWxq35JYBjwKn3ZU+K\n9QKC0wnSlZDz38sVgiAh9re1VLMrMUnrl0Fm73IWvTrY9lNUcMIkfJAWXmTz\n41IaelFRJFzvvxQ8rZNSYoniSRJP0Plgd7r9c9WYDGcMW8pw0NvFx+7EAzJ2\nfHj+J+lBP0Z4Zr0sLJEbAs+gig4FF6rNP/C/zDRJCtw2fCEUxGfalt2hIubN\nZXQEhKhqcGypubZKeGjVlb+MuLATe681CLqPMt+Uh0GzWGNpdhob8pjB40gn\nSH0Ys5HC3h2hLrgu2v4aOfGSfnSvTQkJN4GnKbQSMyhs4mAfROHyUEI1LHvO\nEMxTfXYB2XxYkFlqdkJLv+8FFBSrtWjsOKrL/nCYMUlvc7740htjgxd+CxAb\nAQNKviy/ni3XeGMNrJRZden9I8hzdtsnDz5t3a4qDQzavKsfYhp5++eZX1sc\ncpyt\r\n=Yfg2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB/5QiZABdiB32UOaI6y9oOL/iaBfn3tSYlFC89kv2/xAiEAlwO+KYNVRumy4WS8Qa80z6NYTwldE9WMGyu9ythFMd8="}]},"_npmUser":{"name":"beskay","email":"beskay0x@gmail.com"},"directories":{},"maintainers":[{"name":"beskay","email":"beskay0x@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/erc721b_1.0.0_1644582095759_0.8436707716017036"},"_hasShrinkwrap":false},"1.0.1":{"name":"@beskay/erc721b","version":"1.0.1","description":"Updated, minimalist and gas efficient version of OpenZeppelins ERC721 contract","scripts":{"node":"hardhat node","test":"hardhat test","test:gas":"REPORT_GAS=true npx hardhat test"},"devDependencies":{"@nomiclabs/hardhat-ethers":"^2.0.4","@nomiclabs/hardhat-waffle":"^2.0.2","chai":"^4.3.6","ethereum-waffle":"^3.4.0","ethers":"^5.5.4","hardhat":"^2.8.3","hardhat-gas-reporter":"^1.0.7","prettier":"^2.5.1","prettier-plugin-solidity":"^1.0.0-beta.19"},"dependencies":{"@openzeppelin/contracts":"^4.4.2"},"author":{"name":"beskay"},"license":"GPL-3.0-or-later","repository":{"type":"git","url":"git+https://github.com/beskay/ERC721B.git"},"gitHead":"422b97e192c31511857b9f9059689b7c92ccc005","bugs":{"url":"https://github.com/beskay/ERC721B/issues"},"homepage":"https://github.com/beskay/ERC721B#readme","_id":"@beskay/erc721b@1.0.1","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-5mJ8irBoZ3dnqpysE4ZX+C+GVGFhQvP2p2nvTI+U1j7/f3EnjVT3DiFO6WtvwmbaEV+vIhrQTnqYqaQSknNcJw==","shasum":"61ea3aee268a590f1e6fd3858b23619fe3aec149","tarball":"https://registry.npmjs.org/@beskay/erc721b/-/erc721b-1.0.1.tgz","fileCount":4,"unpackedSize":55454,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiBmPOCRA9TVsSAnZWagAAscYQAIGiw1WWBPexaZx7CqHQ\nNykmQbTa8r3usCqpare/6LYkvTX4zQQIdQVPLEP+lOR+0U7gBZ4BySniKD5w\n8mzkezdImYcGpdklVJCAzZwv6XIZmliE1MDP1fFRmx8UlJ1vd4+MhC75G3FL\nSymTlOtLT8Zl5KPNg96Wd9F776VsGAx8NxjmyCpEoTfsq8WAUrwTmo7795UH\nmsTlCrP9Ee6KavYmtoS5DG6tFCNWphEwIW/SVqh5YA3+XPTYPEvukE7tWU0X\nJASW9+1Gye7WKK2cuGhB4L6XBRGC3vRJnmZB2B2oyIt4renzki82e39aRX9v\nQJ5EIlxns56W91QetClHWjXbM58lCn/vde3zXg6tbI4an4MASccoz/LTW6WX\nRKkiAQ4Tv2ZiVz8vyFDmzoBQTLHVtKAYjVj6fiDU0pN+7pfNDp++SiBq8hH9\njKiBgrY8B0MG0a1IbrzqS84JYiylWn60kQw6eUrsBtTO6fP2FDKNxYQrHQ5c\ncrQuxnuMhenwWI9MZ7Z9dVCHOXTnGyPog9igX3LtivWhJDKosdDRhRmSnUiD\nxgixq5Vu1oy6nHCAbOv0jtOonUDeKuZsVczfkdMi1JnDt4Yqh7YO7LBRc5SR\noRMNE4WNMYLICaU04ns6vNvj3xixwtP1FPVCMlviDCLJp5kJKt1A5p1SJAOX\nihPm\r\n=BtAi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDEx+XjE6xmXFzYIj1fIGQSrGbxH18P4lV3E1GAlj+Z6gIgblv30XzgjMr4IjTOOMNiRVPK5HyIIWPZzng6w9E4y+w="}]},"_npmUser":{"name":"beskay","email":"beskay0x@gmail.com"},"directories":{},"maintainers":[{"name":"beskay","email":"beskay0x@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/erc721b_1.0.1_1644585934584_0.3964231832948446"},"_hasShrinkwrap":false},"1.0.2":{"name":"@beskay/erc721b","version":"1.0.2","description":"Updated, minimalist and gas efficient version of OpenZeppelins ERC721 contract","scripts":{"node":"hardhat node","test":"hardhat test","test:gas":"REPORT_GAS=true npx hardhat test"},"devDependencies":{"@nomiclabs/hardhat-ethers":"^2.0.4","@nomiclabs/hardhat-waffle":"^2.0.2","chai":"^4.3.6","ethereum-waffle":"^3.4.0","ethers":"^5.5.4","hardhat":"^2.8.3","hardhat-gas-reporter":"^1.0.7","prettier":"^2.5.1","prettier-plugin-solidity":"^1.0.0-beta.19"},"dependencies":{"@openzeppelin/contracts":"^4.4.2"},"author":{"name":"beskay"},"license":"GPL-3.0-or-later","repository":{"type":"git","url":"git+https://github.com/beskay/ERC721B.git"},"gitHead":"be797685fc9cb80ab4d23c1f59ca9835d92e2d54","bugs":{"url":"https://github.com/beskay/ERC721B/issues"},"homepage":"https://github.com/beskay/ERC721B#readme","_id":"@beskay/erc721b@1.0.2","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-I2XrreBtCOf2h6CrHGaus1SBiOX3eKGVPaMDDeWfL+ryFZ2m+c4Aa7G2737O6HEeY5TKtUgQYPBJQ27QV224YA==","shasum":"b03e3d54bb00c35ae5d8a719ee75cf81ba881c25","tarball":"https://registry.npmjs.org/@beskay/erc721b/-/erc721b-1.0.2.tgz","fileCount":4,"unpackedSize":55454,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiDYbyCRA9TVsSAnZWagAAd6QP/0PLxTrXnN/E1gOnXAXD\nY0vst0f9NhcHSY2W2sx5LSZJr1j5KGdFT6NFCGJTzUrEUzuvLj7R9wDTnijU\nrFB7tmHNpEDFOF7OoaDDSbOsDpntQMoFH6VC0sAOwYwBTi6kS3fLCBoNKFWW\nAUp5Zo1U2+I3WT2xb8SQx/DcfcCWteQwep0niGoTHFzmuIjm99grsAwcFc7X\nlX+Sydvjt4ALouKkNAMBD1vqpQDlGoLrDmBGw4N6QYu1z7IkYlEy3XdtEtNf\nqB0Mxl8ByGVK90Ju5Dq4JTXwofCH7TZCJbdydJVZWvuqoidm59y9NCBeS8yC\nQeuVy1kgpik4aiFTmZaqd7Du7O8QWQtb0iw9FR5l+Y4mOq8dErcOcimcbIRh\naoUjN8n9k9wd87AfQJQ5aR8jRbR3cMhWnRD9b1S7F27jgdSrNubAooLLhqf2\nroPS+o+s954gHZbVDAGNNYPFt0qrR2/0FsiEM0obvd9Tub/fPHg0pobTGY6e\n6m4GaqK/oziAm6GYs3KnG95o9UjnUzaqiWujJovOxmG10dQw2FkiAV8FOoJR\nfgQvRu+CxbtJR7KZDwX0+/mIwFkqPa4XeXOYX7zrBPJL+pLDNEZNpKm7nF1m\nMmeCbIf60FjtA4tPw1b/igXhc9UtJsVvR8749Ux2AVTi/uBC/cSBFgGWTaAY\njugg\r\n=qCSZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGy262ANEQwwq+PlFcoyyvQbLipD3cIgFw5390hd/395AiEA6gNNR/80wcyjNO1eVHGTNhmCsdHGuoWfbkkY6BC17RQ="}]},"_npmUser":{"name":"beskay","email":"beskay0x@gmail.com"},"directories":{},"maintainers":[{"name":"beskay","email":"beskay0x@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/erc721b_1.0.2_1645053682713_0.07789901021385415"},"_hasShrinkwrap":false},"1.0.3":{"name":"@beskay/erc721b","version":"1.0.3","description":"Updated, minimalist and gas efficient version of OpenZeppelins ERC721 contract","scripts":{"node":"hardhat node","test":"hardhat test","test:gas":"REPORT_GAS=true npx hardhat test"},"devDependencies":{"@nomiclabs/hardhat-ethers":"^2.0.4","@nomiclabs/hardhat-waffle":"^2.0.2","chai":"^4.3.6","ethereum-waffle":"^3.4.0","ethers":"^5.5.4","hardhat":"^2.8.3","hardhat-gas-reporter":"^1.0.7","prettier":"^2.5.1","prettier-plugin-solidity":"^1.0.0-beta.19"},"dependencies":{"@openzeppelin/contracts":"^4.4.2"},"author":{"name":"beskay"},"license":"GPL-3.0-or-later","repository":{"type":"git","url":"git+https://github.com/beskay/ERC721B.git"},"gitHead":"922ccf79b447cc8f9a275604641e10316d745308","bugs":{"url":"https://github.com/beskay/ERC721B/issues"},"homepage":"https://github.com/beskay/ERC721B#readme","_id":"@beskay/erc721b@1.0.3","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-rFxIV8l3GRfk+2ox1JQ89mM8Xnv1KzHlwcehimmUeji/ItzPRHcjlpI5REUylvQANyOSN6WYK3lVfu5IiCCGFA==","shasum":"c2f97b51136ada34200837fd49dce60bf36f295c","tarball":"https://registry.npmjs.org/@beskay/erc721b/-/erc721b-1.0.3.tgz","fileCount":4,"unpackedSize":56047,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiD9jWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo3JA//VJQTF2XsUMQkf5GfMfWJPsBT/cAs0cFl6K028kZDFbK90tue\r\nSWNa8BUqL8ipCg5IO29CrmpOUgTEQun/eGkLLvs2FKm/mXaQCd1tJaZGJCOb\r\n+ZkuTWA1UuWHIPMJvDudJ5Nleh1xIuO6LWqfc2AJbCNM6g+Llt2098ZMocy1\r\nzAVSs/9I/QY1aqoKloonCeHccvZGONQDfI5ziOCNYGIqShJDLUvuM7K5BsYg\r\nNKPymvYUPk1kpvvLL6mB3jLRpGtIdqfk5WqCXbGmUxp9pY+TEwTS0p7ck33n\r\nQiqZVXdm9yO0sEoBmtDejukdG8cvqKa12FY4xMONaT2yTJKUFdWCh4wzQ4Sq\r\nxUNyDmM3gd/hRZMWUTcGi2ykuQagVsOfprMfyfu2DJJd+TkxlKjoCTor/h2t\r\n+SOswc35U4Frm4JS4moZR47Tq1gyG00ZEk38jjknYViavwZBru82EumnFvSH\r\nyzp5wpNAih/TJwnWzxsxqTvU8G+KHBKen8AfylGrX8DWAlanrowUlBmddDZI\r\ny1mo7qjFgh9aXXho90chkffpjPnc83wceZV9RFzckhfnxB0LpNtfkTD5SQ3I\r\nLizowySw2EwcNXrTleijQfzH+L6Mekr+L0ZlIFoSEXP1wF18DVPg6i/N69U3\r\nz0ZQKHx7X4nFyS0NINi6FiaviUVPk4XTqpE=\r\n=WiLz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDX+5Heikq5wcwMO/1vJHFGyDIDGTevEdMKGaSEObnGyAIgDYSUJzeRxOdeFpJ/eTMzIoPp/WjpiwYRJktepEbQJrY="}]},"_npmUser":{"name":"beskay","email":"beskay0x@gmail.com"},"directories":{},"maintainers":[{"name":"beskay","email":"beskay0x@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/erc721b_1.0.3_1645205717934_0.9396620858166509"},"_hasShrinkwrap":false},"1.0.4":{"name":"@beskay/erc721b","version":"1.0.4","description":"Updated, minimalist and gas efficient version of OpenZeppelins ERC721 contract","scripts":{"node":"hardhat node","test":"hardhat test","test:gas":"REPORT_GAS=true npx hardhat test"},"devDependencies":{"@nomiclabs/hardhat-ethers":"^2.0.4","@nomiclabs/hardhat-waffle":"^2.0.2","chai":"^4.3.6","ethereum-waffle":"^3.4.0","ethers":"^5.5.4","hardhat":"^2.8.3","hardhat-gas-reporter":"^1.0.7","prettier":"^2.5.1","prettier-plugin-solidity":"^1.0.0-beta.19"},"dependencies":{"@openzeppelin/contracts":"^4.4.2"},"author":{"name":"beskay"},"license":"GPL-3.0-or-later","repository":{"type":"git","url":"git+https://github.com/beskay/ERC721B.git"},"gitHead":"8fe10092d64b33982038c1b756f19a7736b19a56","bugs":{"url":"https://github.com/beskay/ERC721B/issues"},"homepage":"https://github.com/beskay/ERC721B#readme","_id":"@beskay/erc721b@1.0.4","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-4bfSYfIin9TK2w1dcmEzVwlv/SN/hGZlf1EGadSaSsSomHAIz1okSbL+D2YmqNXYNwEBCbqwOMcoD/HfRpBB2g==","shasum":"7ab4959b8006953ec9f91fc23b02e7281fbdf990","tarball":"https://registry.npmjs.org/@beskay/erc721b/-/erc721b-1.0.4.tgz","fileCount":4,"unpackedSize":56549,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiHRoRACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrGbw//aLZmNmngN8HbwvvTq5mJNE/cC8Xt0iqR6dobruXkKKmCb348\r\nzIexzcax6lmpyrqWkQM7bWxDS1M/u2kxgxBfUdDS7L4vWvPlMPNSZckETD6E\r\nSVM42Yu2YwOtLaywzwafFjbudyy8GQxJKdJ77pUyWZbxJVBJM4oSmoC+V5mp\r\nEVeSESwk38eLmjATjgRtiQHRoRJ6oE6qfHdyprUVCDtDzsmA2tFw+r2fsP1T\r\nWg4kZpINBUBPUDcy0LPpAnh9wh434Z4STtwuakQB4RC1Hyf5Z5HT4VC5zxER\r\n8aLfdd1iZrvzvKGsgJB5QyhsURX0oZBw7fCtjr5IPfP5WmHX2wJff5T/YJpt\r\nwEUtQ6hwDnIwqysaZ0gjt5XAuF5YWYnqRMOf7BqcvWKHHKfqnEO5HYVBqdp0\r\nq3Z7ZrcN+X642GziFnjiJQhfNeIsA3K3lYWLRjuYUw19NSSvHJkCc+xnw/Iv\r\nvK0hAyUtvH9LgnN2YCm2Nq8a/vNAfAVVzztBMjb0vRPWmTawwRqbdkiLGgFF\r\n2eyJVt5h/xFza5ybo7VSvZLbMhcbjXU3Pa7IzkNYsUO63H3AVAF/58rbvwXh\r\n2rjyPgg4sFbmKaeoa1e2Pg5q07XP1n9nZYU4T2zXH0i+be5vIUjgWXgQ0Thg\r\nYnp/ZZ6LZwd952vfMsZXjBmnB36RlNztcIc=\r\n=i2v+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGRv5horcvtCY9I/FpHHm2W0BNLfQYIE6CJVLK+GjOPnAiA1mCOLXr+a5SpyTVxCyTdY0c3C0Mrnt7NRFLXml3/iLw=="}]},"_npmUser":{"name":"beskay","email":"beskay0x@gmail.com"},"directories":{},"maintainers":[{"name":"beskay","email":"beskay0x@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/erc721b_1.0.4_1646074385133_0.2805459306591953"},"_hasShrinkwrap":false}},"time":{"created":"2022-02-11T12:21:35.688Z","1.0.0":"2022-02-11T12:21:35.908Z","modified":"2022-04-04T18:32:58.929Z","1.0.1":"2022-02-11T13:25:34.746Z","1.0.2":"2022-02-16T23:21:22.895Z","1.0.3":"2022-02-18T17:35:18.067Z","1.0.4":"2022-02-28T18:53:05.312Z"},"maintainers":[{"name":"beskay","email":"beskay0x@gmail.com"}],"description":"Updated, minimalist and gas efficient version of OpenZeppelins ERC721 contract","homepage":"https://github.com/beskay/ERC721B#readme","repository":{"type":"git","url":"git+https://github.com/beskay/ERC721B.git"},"author":{"name":"beskay"},"bugs":{"url":"https://github.com/beskay/ERC721B/issues"},"license":"GPL-3.0-or-later","readme":"# ERC721B\n\nA fully compliant implementation of IERC721 with significant gas savings for minting multiple NFTs in a single transaction. Includes the Metadata and Enumerable extension.\n\nThe ERC721B standard builds on top of ERC721A from Azuki, reducing the minting fees by around ~17k gas on average and the transfer fees by around ~7k gas.\n\nThe table below shows a comparison of gas costs between a standard ERC721Enumerable contract, an ERC721A contract and this ERC721B contract. The two columns on the right show the gas savings compared to an ERC721Enumerable contract and compared to an ERC721A contract.\n\n![Table of gas savings](https://i.imgur.com/A9LKIFA.png)\n\n## How it works\n\n### Removed OpenZeppelins Enumerable implementation\n\nOut of the box, Open Zeppelin ERC721Enumerable comes with an inordinate amount of transfer processing that simply is not needed for the majority of projects. With ERC721B, the method of tracking is moved into view functions, this saves an huge amount of gas when minting or transferring your tokens. For more info on that, I highly recommend reading [this medium article from nftchance](https://medium.com/coinmonks/the-cannibalization-of-nfts-by-openzeppelin-by-insanely-high-gas-prices-cd2c9a7c1e7).\n\n### Included optimizations from ERC721A\n\nI included the optimizations from Azukis ERC721A contract, namely updating the owners balance only once per batch mint request, instead of per minted NFT. Thanks to this, minting is cheap -- no matter how many NFTs you mint at once. For more info, see [Azukis blog post](https://www.azuki.com/erc721a)\n\n### Using an array as owner storage\n\nThis is actually the \"secret ingredient\", the reason why this implementation is even more gas efficient than ERC721A. Instead of using mappings to store the owner data, we use an array. So\n\n```\nstruct AddressData {\n    uint128 balance;\n    uint128 numberMinted;\n}\n// Mapping owner address to address data\nmapping(address => AddressData) private _addressData;\n\nuint256 internal currentIndex = 0;\n```\n\nBecomes\n\n```solidity\n// Array which maps token ID to address (index is tokenID)\naddress[] internal _owners;\n```\n\nThe balance variable is substituded with a **_balanceOf()_** function call, numberMinted is removed, **_currentIndex_** can be replaced with **_\\_owners.length_**. This saves us a few storage writes and therefore some gas.\n\nFollowing storage writes in the mint function of ERC721A\n\n```solidity\n_addressData[to].balance += uint128(quantity);\n_addressData[to].numberMinted += uint128(quantity);\n\n_ownerships[startTokenId].addr = to;\n_ownerships[startTokenId].startTimestamp = uint64(block.timestamp);\n\n...\n\ncurrentIndex = updatedIndex;\n```\n\nare substituded with\n\n```solidity\n_owners.push(to);\n```\n\nIn the image below you can see an example layout of the **_\\_owners_** array:\n\n![owners array](https://i.imgur.com/x1NUoO1.png)\n\nIn this example wallet **_0x1234...6789_** minted 3 tokens and wallet **_0x4567...8745_** minted 4 tokens (**_0x9876...1234_** minted an unknown number of tokens since the previous owner isnt shown).\n\nAs you can see, an owner is only set for the last minted tokenId, the previous ones keep their default value. Over time (after every token got transferred at least once) all indices will be set to a specific owner.\n\n### \\_checkOnERC721Received\n\nUnlike in the standard ERC721 implementation this is only called once per batch mint. Calling this several times per batch mint is a waste of gas, if the contract confirms the receival of one token, it will accept all additional tokens too. This saves us around 5k gas per additional mint, so it adds up quite a bit.\n\nPlease note that this is an experimental feature, it could be that there are some contracts out there which use the onERC721Received function for additional logic, like sending the received NFTs to another wallet or something else, I am not aware of any though.\n\n## Installation\n\n```sh\nnpm install --save-dev @beskay/erc721b\n```\n\n## How to use\n\nOnce installed simply import the contract and inherit from it.\n\n```solidity\npragma solidity ^0.8.4;\n\nimport '@beskay/erc721b/contracts/ERC721B.sol';\n\ncontract Example is ERC721B {\n  constructor() ERC721B('Example', 'EXMP') {}\n\n  function mint(uint256 quantity) external payable {\n    // _safeMint's second argument now takes in a quantity, not a tokenId.\n    _safeMint(msg.sender, quantity);\n  }\n}\n```\n\nYou can also take a look at [ERC721BMock.sol](https://github.com/beskay/ERC721B/blob/main/contracts/mocks/ERC721BMock.sol)\n\n## Recommendations\n\n### Keep max batch size limit low\n\nEven if minting multiple tokens at once is cheap, dont set the max batch limit too high. The higher the max batch limit, the higher are the gas costs of subsequent transfers -- on average. This is due to the **_ownerOf()_** function, which iterates over the **_\\_owners array_** until it finds a nonzero element, so gas spent here starts off proportional to the maximum mint batch size. It gradually moves to O(1) as tokens get transferred around in the collection over time.\n\n### Dont call balanceOf() and tokenOfOwnerByIndex() on chain\n\nThe gas savings by using an **_\\_owners_** array instead of a mapping comes at a cost: The **_balanceOf()_** and **_tokenOfOwnerByIndex()_** are highly inefficient. They iterate over the complete array, this means if a collection has 10000 NFTs in total, they will iterate over 10k items.\n\nBecause of this, calling these functions from another smart contract can become extremely expensive, e.g. calling the **_balanceOf()_** function from a 10k NFT project costs around 22 million (!) gas, 2/3 of the block gas limit.\n\nFortunately, calling those two functions from another smart contract is almost never needed and if it is, you can probably substitute the call off chain: Usually you call balanceOf() to check if someone holds NFTs from a specific project in order to whitelist them (or something similiar). Instead of calling **_balanceOf()_** from your smart contract, you can check the tokenIds a wallet holds by calling **_tokenOfOwnerByIndex()_** off chain, and then prove it on chain by calling **_ownerOf(tokenId)_**.\n\n## Safety\n\nThis is **experimental software** and is provided on an \"as is\" and \"as available\" basis. This contract is not audited yet.\n\nIt was **not designed with user safety** in mind. You should thoroughly read the contract before using it for your own project.\n\nI **do not give any warranties** and **will not be liable for any loss** incurred through any use of this codebase.\n\n## FAQ\n\n### How does it compare to ERC721A?\n\nERC721A is designed with user safety in mind, ERC721B is designed for maximum gas savings. Its a \"lightweight\" ERC721A contract, so to say. This contract is still absolutely fine and safe to use, just remember that calling balanceOf() and tokenOfOwnerByIndex() on chain should be avoided.\n\n### How can i save even more gas?\n\nIf you dont want to support minting to smart contracts, you can use the **_mint_** function instead of **_safeMint_**. This saves you another ~8k gas, since **_\\_checkOnERC721Received_** wont be called. Make sure that smart contracts wont be able to mint to prevent loss of NFTs, e.g. by using a whitelist.\n\n### Why is the contract marked as abstract?\n\nThe contract is marked as abstract because the **tokenURI** function is not implemented.\n\n## Acknowledgements\n\nThese contracts were inspired by or directly modified from many sources, primarily:\n\n- [ERC721A](https://github.com/chiru-labs/ERC721A)\n- [solmate](https://github.com/Rari-Capital/solmate)\n- [OpenZeppelin](https://github.com/OpenZeppelin/openzeppelin-contracts)\n\nA big influence was also [this medium article from nftchance](https://medium.com/coinmonks/the-cannibalization-of-nfts-by-openzeppelin-by-insanely-high-gas-prices-cd2c9a7c1e7)\n\n## Contact\n\n- Twitter - [@beskay0x](https://twitter.com/beskay0x)\n- Discord - [TheUnmasked](https://discord.gg/theunmasked)","readmeFilename":"README.md"}