-
-
Save shobhitic/9c281505002a50d95e55b4c261e3d477 to your computer and use it in GitHub Desktop.
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>LazyMinting</title> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ethers/5.6.9/ethers.umd.min.js"></script> | |
</head> | |
<body> | |
<script type="text/javascript"> | |
const SIGNING_DOMAIN_NAME = "Voucher-Domain" | |
const SIGNING_DOMAIN_VERSION = "1" | |
const chainId = 1 | |
const contractAddress = "0xa131AD247055FD2e2aA8b156A11bdEc81b9eAD95" // Put the address here from remix | |
const signer = new ethers.Wallet("503f38a9c967ed597e47fe25643985f032b072db8075426a92110f82df48dfcb") // private key that I use for address 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4 | |
const domain = { | |
name: SIGNING_DOMAIN_NAME, | |
version: SIGNING_DOMAIN_VERSION, | |
verifyingContract: contractAddress, | |
chainId | |
} | |
async function createVoucher(tokenId, price, uri, buyer) { | |
const voucher = { tokenId, price, uri, buyer } | |
const types = { | |
LazyNFTVoucher: [ | |
{name: "tokenId", type: "uint256"}, | |
{name: "price", type: "uint256"}, | |
{name: "uri", type: "string"}, | |
{name: "buyer", type: "address"} | |
] | |
} | |
const signature = await signer._signTypedData(domain, types, voucher) | |
return { | |
...voucher, | |
signature | |
} | |
} | |
async function main() { | |
const voucher = await createVoucher(5, 50, "uri", "0x5B38Da6a701c568545dCfcB03FcB875f56beddC4") // the address is the address which receives the NFT | |
console.log(`[${voucher.tokenId}, ${voucher.price}, "${voucher.uri}", "${voucher.buyer}", "${voucher.signature}"]`) | |
} | |
</script> | |
</body> | |
</html> |
// SPDX-License-Identifier: MIT | |
pragma solidity ^0.8.4; | |
import "@openzeppelin/[email protected]/token/ERC721/ERC721.sol"; | |
import "@openzeppelin/[email protected]/token/ERC721/extensions/ERC721URIStorage.sol"; | |
import "@openzeppelin/[email protected]/access/Ownable.sol"; | |
import "@openzeppelin/[email protected]/utils/cryptography/draft-EIP712.sol"; | |
contract LazyNFT is ERC721, ERC721URIStorage, Ownable, EIP712 { | |
string private constant SIGNING_DOMAIN = "Voucher-Domain"; | |
string private constant SIGNATURE_VERSION = "1"; | |
address public minter; | |
constructor(address _minter) ERC721("LazyNFT", "LNFT") EIP712(SIGNING_DOMAIN, SIGNATURE_VERSION) { | |
minter = _minter; | |
} | |
struct LazyNFTVoucher { | |
uint256 tokenId; | |
uint256 price; | |
string uri; | |
address buyer; | |
bytes signature; | |
} | |
function recover(LazyNFTVoucher calldata voucher) public view returns (address) { | |
bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( | |
keccak256("LazyNFTVoucher(uint256 tokenId,uint256 price,string uri,address buyer)"), | |
voucher.tokenId, | |
voucher.price, | |
keccak256(bytes(voucher.uri)), | |
voucher.buyer | |
))); | |
address signer = ECDSA.recover(digest, voucher.signature); | |
return signer; | |
} | |
function safeMint(LazyNFTVoucher calldata voucher) | |
public | |
payable | |
{ | |
require(minter == recover(voucher), "Wrong signature."); | |
require(msg.value >= voucher.price, "Not enough ether sent."); | |
_safeMint(voucher.buyer, voucher.tokenId); | |
_setTokenURI(voucher.tokenId, voucher.uri); | |
} | |
// The following functions are overrides required by Solidity. | |
function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { | |
super._burn(tokenId); | |
} | |
function tokenURI(uint256 tokenId) | |
public | |
view | |
override(ERC721, ERC721URIStorage) | |
returns (string memory) | |
{ | |
return super.tokenURI(tokenId); | |
} | |
} |
@damianlluch so only allowed user can mint with the voucher (and not everyone). Also can't front run the transaction.
I keep getting this error when i try and run the contract:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Returned error: {"jsonrpc":"2.0","error":"execution reverted","id":6426425325688160}
any thoughts?
When i force the transaction i get:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
Returned error: {"jsonrpc":"2.0","error":"err: max fee per gas less than block base fee: address 0x27fF22B4AFbF9b7b1de0D832c94142c9E0Edea22, maxFeePerGas: 154311703063 baseFee: 158976875280 (supplied gas 15025147)","id":6426425325688248}
Hi, I found your code very useful.
I have a question for you.
Why do you use the minter variable? What's the point?