Skip to content

Commit

Permalink
MOD: new signature logic
Browse files Browse the repository at this point in the history
  • Loading branch information
cctv2206 committed Mar 20, 2024
1 parent 3493e6a commit e84439a
Show file tree
Hide file tree
Showing 7 changed files with 558 additions and 369 deletions.
79 changes: 28 additions & 51 deletions contracts/aime/AIMeFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol";

contract AIMeFactory is Ownable {
address public aimeSigner;
uint256 public protocolFee = 0.001 ether;

constructor() Ownable(msg.sender) {}
Expand All @@ -31,10 +30,8 @@ contract AIMeFactory is Ownable {
event Received(address sender, uint amount);

mapping(address => uint256) public addressNonce;

function updateSigner(address _signer) external onlyOwner {
aimeSigner = _signer;
}
mapping(address => address) public aimeSigners;
mapping(string => address) public aimeAddresses;

function updateProtocolFee(uint256 _fee) external onlyOwner {
protocolFee = _fee;
Expand All @@ -43,11 +40,10 @@ contract AIMeFactory is Ownable {
function _genMessageHash(
address creatorAddress,
address aimeAddress,
string memory aimeName,
uint256 tokenId,
string memory key,
string memory dataType,
string memory data,
string memory avatar,
string memory image,
uint256 amount,
uint256 nonce
Expand All @@ -57,56 +53,30 @@ contract AIMeFactory is Ownable {
abi.encodePacked(
creatorAddress,
aimeAddress,
aimeName,
tokenId,
key,
dataType,
data,
avatar,
image,
amount,
nonce
)
);
}

function _genMessageHashForUpdate(
address creatorAddress,
address aimeAddress,
uint256 tokenId,
string memory data,
string memory image,
uint256 nonce
) private pure returns (bytes32) {
return
keccak256(
abi.encodePacked(
creatorAddress,
aimeAddress,
tokenId,
data,
image,
nonce
)
);
}

function createAIME(
string memory name_,
string memory symbol_,
string memory avatar_,
string memory bio_,
string memory image_,
bytes memory signature,
uint256 creatorRewardAmount
address aimeSigner
) public payable {
require(msg.value >= protocolFee, "Insufficient payment");
bytes32 _msgHash = MessageHashUtils.toEthSignedMessageHash(
_genMessageHash(msg.sender, msg.sender, name_, "basic_prompt", "static", bio_, avatar_, image_, 0, addressNonce[msg.sender])
);
require(aimeSigner != address(0) && ECDSA.recover(_msgHash, signature) == aimeSigner, "Invalid signature");
addressNonce[msg.sender] += 1;

AIMeNFT aime = new AIMeNFT(string(abi.encodePacked("AIME:", name_)), symbol_, avatar_, bio_, image_, msg.sender, creatorRewardAmount);
require(aimeAddresses[name_] == address(0), "AIME already exists");
AIMeNFT aime = new AIMeNFT(string(abi.encodePacked("AIME:", name_)), name_, avatar_, bio_, image_);
address aimeAddress = address(aime);
aimeAddresses[name_] = aimeAddress;
aimeSigners[aimeAddress] = aimeSigner;
emit AIMeCreated(msg.sender, address(aime));
}

Expand All @@ -120,12 +90,15 @@ contract AIMeFactory is Ownable {
bytes memory signature
) public payable {
require(msg.value >= protocolFee, "Insufficient payment");
bytes32 _msgHash = MessageHashUtils.toEthSignedMessageHash(
_genMessageHash(msg.sender, aimeAddress, "", key, dataType, data, "", image, amount, addressNonce[msg.sender])
);
require(aimeSigner != address(0) && ECDSA.recover(_msgHash, signature) == aimeSigner, "Invalid signature");
addressNonce[msg.sender] += 1;

address signer = aimeSigners[aimeAddress];
if (signer != address(0)) {
bytes32 _msgHash = MessageHashUtils.toEthSignedMessageHash(
_genMessageHash(msg.sender, aimeAddress, 0, key, dataType, data, image, amount, addressNonce[msg.sender])
);
require(ECDSA.recover(_msgHash, signature) == signer, "Invalid signature");
addressNonce[msg.sender] += 1;
}

AIMeNFT aime = AIMeNFT(aimeAddress);
uint256 tokenId = aime.safeMint(msg.sender, key, dataType, data, image, amount);
emit AIMeNFTMinted(
Expand All @@ -147,11 +120,15 @@ contract AIMeFactory is Ownable {
bytes memory signature
) public payable {
require(msg.value >= protocolFee, "Insufficient payment");
bytes32 _msgHash = MessageHashUtils.toEthSignedMessageHash(
_genMessageHashForUpdate(msg.sender, aimeAddress, tokenId, data, image, addressNonce[msg.sender])
);
require(aimeSigner != address(0) && ECDSA.recover(_msgHash, signature) == aimeSigner, "Invalid signature");
addressNonce[msg.sender] += 1;
address signer = aimeSigners[aimeAddress];
if (signer != address(0)) {
bytes32 _msgHash = MessageHashUtils.toEthSignedMessageHash(
_genMessageHash(msg.sender, aimeAddress, tokenId, "", "", data, image, 0, addressNonce[msg.sender])
);
require(ECDSA.recover(_msgHash, signature) == signer, "Invalid signature");
addressNonce[msg.sender] += 1;
}

AIMeNFT aime = AIMeNFT(aimeAddress);
aime.updateAIMeInfo(tokenId, msg.sender, data, image);
emit AIMeNFTUpdated(msg.sender, aimeAddress, tokenId, data);
Expand Down
20 changes: 8 additions & 12 deletions contracts/aime/AIMeNFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ contract AIMeNFT is ERC721, Ownable, ERC721Holder {
uint256 public constant AIME_POWER_TOTAL_AMOUNT = 1000000 * 1e18;
uint256 public constant AIME_NFT_PRICE_FACTOR = 12;
uint256 public constant AIME_POWER_TRADE_MIN_AMOUNT = 0.0001 * 1e18;
uint256 public CREATOR_REWARD_AMOUNT;
uint256 public aimePowerReserved;
address public aimePowerAddress;
string public avatar;
Expand Down Expand Up @@ -61,19 +60,12 @@ contract AIMeNFT is ERC721, Ownable, ERC721Holder {
string memory symbol_,
string memory avatar_,
string memory bio_,
string memory image_,
address sender,
uint256 creatorRewardAmount
string memory image_
) ERC721(name_, symbol_) Ownable(msg.sender) {
require(creatorRewardAmount > 0 && creatorRewardAmount <= AIME_POWER_TOTAL_AMOUNT, "Creator Reward Amount out of bound.");
_factory = _msgSender();

AIMePower aimePower = new AIMePower(name_, symbol_);
CREATOR_REWARD_AMOUNT = creatorRewardAmount;
aimePower.mint(address(this), creatorRewardAmount);
// todo: mint tokens to creator?
// aimePower.mint(sender, AIME_POWER_TOTAL_AMOUNT - creatorRewardAmount);
aimePowerReserved = creatorRewardAmount;
aimePower.mint(address(this), AIME_POWER_TOTAL_AMOUNT);
aimePowerReserved = AIME_POWER_TOTAL_AMOUNT;
aimePowerAddress = address(aimePower);

avatar = avatar_;
Expand Down Expand Up @@ -264,6 +256,8 @@ contract AIMeNFT is ERC721, Ownable, ERC721Holder {
_requireOwned(tokenId);

string memory imageUrl = tokenContents[tokenId].image;
string memory chatUrl = string(abi.encodePacked('https://app.aime.bot/chat/', Strings.toHexString(uint256(uint160(address(this))), 20), '/', tokenId.toString()));
string memory tradeUrl = string(abi.encodePacked('https://aime.parami.io/#/?address=', Strings.toHexString(uint256(uint160(address(this))), 20), '&tokenId=', tokenId.toString()));

// todo: add traits
string memory json = Base64.encode(
Expand All @@ -276,7 +270,9 @@ contract AIMeNFT is ERC721, Ownable, ERC721Holder {
tokenId.toString(),
'", "description": "A block of content of ',
name(),
'. Go to https://app.aime.bot/chat/',Strings.toHexString(uint256(uint160(address(this))), 20), '/', tokenId.toString(), '", "amount": "',
'. Chat with this AIME ', chatUrl,
' or trade at ', tradeUrl,
'", "amount": "',
tokenContents[tokenId].amount.toString(),
'", "image": "',
imageUrl,
Expand Down
24 changes: 20 additions & 4 deletions hardhat.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const config: HardhatUserConfig = {
settings: {
optimizer: {
enabled: true,
runs: 200,
runs: 100,
},
metadata: {
bytecodeHash: "none",
Expand All @@ -59,8 +59,8 @@ const config: HardhatUserConfig = {
optimismSepolia: {
url: `https://optimism-sepolia.infura.io/v3/${process.env.INFURA_API_KEY}`,
accounts:
process.env.TESTNET_PRIVATE_KEY_AIME_TEST !== undefined
? [process.env.TESTNET_PRIVATE_KEY_AIME_TEST]
process.env.TESTNET_PRIVATE_KEY !== undefined
? [process.env.TESTNET_PRIVATE_KEY]
: [],
},
goerli: {
Expand Down Expand Up @@ -91,6 +91,14 @@ const config: HardhatUserConfig = {
? [process.env.TESTNET_PRIVATE_KEY_AIME_TEST]
: [],
},
arbitrumSepolia: {
url: "https://sepolia-rollup.arbitrum.io/rpc",
chainId: 421614,
accounts:
process.env.TESTNET_PRIVATE_KEY !== undefined
? [process.env.TESTNET_PRIVATE_KEY]
: [],
},
localhost: {
url: `http://localhost:8545`,
accounts: [
Expand All @@ -104,7 +112,7 @@ const config: HardhatUserConfig = {
currency: "USD",
},
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY,
apiKey: process.env.ARBISCAN_API_KEY,
customChains: [
{
network: "scrollSepolia",
Expand All @@ -122,6 +130,14 @@ const config: HardhatUserConfig = {
browserURL: "https://sepolia-optimism.etherscan.io/",
},
},
{
network: "arbitrumSepolia",
chainId: 421614,
urls: {
apiURL: "https://api-sepolia.arbiscan.io/api",
browserURL: "https://sepolia.arbiscan.io/",
},
},
],
},
contractSizer: {
Expand Down
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"clear-cache": "rm -rf artifacts/ cache/ typechain/",
"deploy-sepolia": "npx hardhat run --network sepolia ./scripts/gptminer/deploy_gptminer.ts",
"deploy-aime": "npx hardhat run --network sepolia ./scripts/aime/deploy_aime.ts",
"deploy-aime-op-sepolia": "npx hardhat run --network optimismSepolia ./scripts/aime/deploy_aime.ts",
"verify-aime-op-sepolia": "npx hardhat verify --contract contracts/aime/AIMeFactory.sol:AIMeFactory --network optimismSepolia",
"deploy-aime-arb-sepolia": "npx hardhat run --network arbitrumSepolia ./scripts/aime/deploy_aime.ts",
"verify-aime-arb-sepolia": "npx hardhat verify --contract contracts/aime/AIMeFactory.sol:AIMeFactory --network arbitrumSepolia",
"deploy-nft": "npx hardhat run --network sepolia ./scripts/aime/deploy_test.ts",
"verify-nft": "npx hardhat verify --contract contracts/aime/MockNFT.sol:MockNFT --network sepolia",
"verify-sepolia": "npx hardhat verify --contract contracts/gptmining/GPTMinerV2.sol:GPTMinerV2 --network sepolia",
Expand Down
36 changes: 36 additions & 0 deletions scripts/gas-test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { ethers } from "hardhat";
// import currency from "currency.js"

// const gasPrice = ethers.parseUnits("60", "gwei")
// const etherPrice = currency(2600)

// Assuming you have an async function where you deploy the contract
async function main() {
const [deployer] = await ethers.getSigners();

console.log("Deploying contracts with the account:", deployer.address);

// Assuming `YourContract` is the contract you want to deploy
const YourContract = await ethers.getContractFactory("AIMeFactory");
const yourContract = await YourContract.deploy(); // Add constructor arguments if any

await yourContract.deployed();

console.log("YourContract deployed to:", yourContract.address);

// Get the transaction receipt
const transactionReceipt = await ethers.provider.getTransactionReceipt(yourContract.deployTransaction.hash);

console.log("Gas used for deployment:", transactionReceipt.gasUsed.toString());
const gasPrice = 130; // gwei
const gasCost = gasPrice * Number(transactionReceipt.gasUsed);
const gasCostInEth = ethers.utils.formatUnits(gasCost.toString(), 'gwei');
console.log("Gas cost for deployment:", gasCostInEth, "ETH");
}

main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
Loading

0 comments on commit e84439a

Please sign in to comment.