1. 说是链游公司,但是没问游戏相关的,问的主要还是合约
2. 面试:简单的自我介绍+简历上的项目 + chainlink vrf 原理 + 代理合约的原理
3.chainlink vrf 原理:Chainlink 预言机是一个去中心化网络,在网络中有很多预言机节点,每个预言机节点都可以通过自己的渠道去获取数据,然后在去中心化网络中对获得的数据进行共识。采用的共识方式是中位数。用户传入一个种子给 VRF 合约,预言机 VRF 节点会使用节点私钥和种子生成一个随机数和 Proof (证明) 返回给 VRF 合约,VRF 合约 Proof 验证随机数的合法性,如果通过验证,就会把随机数返回给用户。
4. 代理合约的原理:用户与 A 合约交互,A 合调用 B 合约,A 合约是代理合约,B 合约是逻辑合约,如果想升级,只要去改变 A 合约的内容,但是升级的过程中,不能改变 A 合约的内存布局,只能增,不能删,改。
5. 笔试:权限控制 + 所有权转移 + modifier +event 开关 + Ierc20 转账 + 白名单(加分项)+eoa(加分项)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "ERC721";
import "IERC20";
contract Minter is ERC721 {
address erc20;
address owner;
struct Project {
uint256 eventId;
uint256 timeEnd;
address payAddress;
uint256 price;
bool state;
uint8 amount;
}
Project[] projects;
mapping(address => bool) public whiteBool;
mapping(uint256 => Project) mintEvents;
constructor() {
owner = msg.sender;
}
modifier onlyOwner() {
require(msg.sender == owner, "not owner");
_;
}
function ownerTransfer(address owner_) onlyOwner {
owner = owner_;
}
function stopEvent(uint256 k) onlyOwner {
projects[k].state = false;
}
function white() onlyOwner {
whiteBool[msg.sender] = true;
}
function setupEvent(
uint256 eventId_,
uint256 timeEnd,
address payAddress_,
uint256 price_,
uint256 amount_
) onlyOwner {
projects.push(
Project(eventId_, timeEnd_, payAddress_, price_, amount_)
);
}
function mint(uint256 k) public {
require((projects[k].amount < 100, "exeed");
require(projects[k].state = true, "not start");
require(whiteBool[msg.sender] == true, "not white");
require(msg.sender == tx.origin, "not eoa");
projects[k].amount = amount + 1;
IERC20(erc20).safeTransferFrom(
msg.sender,
projects[k].payAddress,
projects[k].price * 1e18
);
}
}