账户
0xb1...282d
0xB1...282D

0xB1...282D

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.3.9+commit.66b96705
语言
Vyper
合同源代码
文件 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": [
    "."
  ]
}
ABI
[{"anonymous":false,"inputs":[{"indexed":true,"name":"buyer","type":"address"},{"indexed":true,"name":"coord","type":"uint256"},{"indexed":false,"name":"price","type":"uint256"},{"indexed":false,"name":"purchase_count","type":"uint256"}],"name":"PlotPurchase","type":"event"},{"inputs":[{"name":"treasury","type":"address"},{"name":"_token","type":"address"}],"outputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"name":"coord","type":"uint256"}],"name":"buy_plot","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"get_all_owners","outputs":[{"name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"start_index","type":"uint256"}],"name":"get_all_owners","outputs":[{"name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"start_index","type":"uint256"},{"name":"end_index","type":"uint256"}],"name":"get_all_owners","outputs":[{"name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"get_all_purchase_counts","outputs":[{"name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"start_index","type":"uint256"}],"name":"get_all_purchase_counts","outputs":[{"name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"start_index","type":"uint256"},{"name":"end_index","type":"uint256"}],"name":"get_all_purchase_counts","outputs":[{"name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"coord","type":"uint256"}],"name":"price","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"uint256"}],"name":"grid","outputs":[{"components":[{"name":"owner","type":"address"},{"name":"purchase_count","type":"uint256"}],"name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"name":"arg0","type":"address"}],"name":"plots_owned","outputs":[{"name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"stateMutability":"view","type":"function"}]