文件 1 的 1:Grid.vy
# @version ^0.3.9
# @title Grid
from vyper.interfaces import ERC20Detailed
struct Plot:
owner: address
purchase_count: uint256
grid: public(HashMap[uint256, Plot])
BASE_PRICE: constant(uint256) = 10 ** 16
plots_owned: public(HashMap[address, uint256])
treasury: public(address)
token: public(immutable(address))
mint_per_plot: immutable(uint256)
interface MintableToken:
def mint(to: address, amount: uint256): nonpayable
event PlotPurchase:
buyer: indexed(address)
coord: indexed(uint256)
price: uint256
purchase_count: uint256
@external
def __init__(treasury: address, _token: address):
self.treasury = treasury
token = _token
mint_per_plot = 100 * 10 ** convert(ERC20Detailed(token).decimals(), uint256)
@payable
@external
def buy_plot(coord: uint256):
assert coord < 10000, "Invalid coord"
# plot price increases by 2x each time it is purchased
plot_price: uint256 = BASE_PRICE * (2 ** self.grid[coord].purchase_count)
current_owner: address = self.grid[coord].owner
assert msg.value >= plot_price, "Not enough ETH sent to buy plot"
if msg.value > plot_price:
send(msg.sender, msg.value - plot_price)
# protocol takes 25% of the purchase price
# 75% goes to the previous owner
# if there is no previous owner, 100% goes to the protocol
# the protocol is the owner of all plots at the start
if current_owner != ZERO_ADDRESS:
send(current_owner, plot_price * 3 / 4)
if current_owner != msg.sender:
self.plots_owned[current_owner] -= 1
self.plots_owned[msg.sender] += 1
self.grid[coord].owner = msg.sender
else:
self.grid[coord].owner = msg.sender
self.plots_owned[msg.sender] += 1
send(self.treasury, self.balance)
self.grid[coord].purchase_count += 1
# mint tokens for the buyer
MintableToken(token).mint(msg.sender, mint_per_plot)
log PlotPurchase(msg.sender, coord, plot_price, self.grid[coord].purchase_count)
@view
@external
def get_all_owners(start_index: uint256 = 0, end_index: uint256 = 10000) -> DynArray[address, 10000]:
owners: DynArray[address, 10000] = []
for coord in range(start_index, start_index + 10000):
if coord >= end_index:
break
owners.append(self.grid[coord].owner)
return owners
@view
@external
def get_all_purchase_counts(start_index: uint256 = 0, end_index: uint256 = 10000) -> DynArray[uint256, 10000]:
purchase_counts: DynArray[uint256, 10000] = []
for coord in range(start_index, start_index + 10000):
if coord >= end_index:
break
purchase_counts.append(self.grid[coord].purchase_count)
return purchase_counts
@view
@external
def price(coord: uint256) -> uint256:
return BASE_PRICE * (2 ** self.grid[coord].purchase_count)
{
"compilationTarget": {
"Grid.vy": "Grid"
},
"outputSelection": {
"Grid.vy": [
"abi",
"ast",
"interface",
"ir",
"userdoc",
"devdoc",
"evm.bytecode.object",
"evm.bytecode.opcodes",
"evm.deployedBytecode.object",
"evm.deployedBytecode.opcodes",
"evm.deployedBytecode.sourceMap",
"evm.methodIdentifiers"
]
},
"search_paths": [
"."
]
}