dob / auctionhouse

Ethereum based auction platform for non fungible on chain goods
MIT License
117 stars 46 forks source link

Auctionhouse project

This is a platform for auctioning non fungible on chain goods. The below are work in progress notes that we can update and point to as we develop the project.

Running the Dapp locally

You can run the app locally using truffle.

git clone https://github.com/dob/auctionhouse.git
cd auctionhouse
npm install -g truffle     // if not already installed
npm install truffle-default-builder --save
truffle serve

You'll need to either be running a local ethereum node, or be using an Ethereum browser like Mist or Metamask. Point your Ethereum browser at the Ropsten TestNet.

Access your locally running app at http://localhost:8080

Protocol

Implement an on chain set of smart contracts to govern auctions for non-fungible on chain goods. If someone wants to auction off a specific token which either doesn’t have liquidity on an exchange, or is unique, or is representative of some power or job in a network, then they can do so via the auctionhouse platform. The platform will allow the seller to:

It will allow bidding from other users

It will facilitate the transfer of the asset

It will provide for a distribution incentive

Use Cases

This is meant to facilitate auctioning off any non-fungible on-chain asset. Anything represented by an interfaced non-fungible asset (not ERC20, but need to find equivalent...ERC-137 is for name registries and may be close?) token can be auctioned.

Technical Standard For Auctionable Items

As mentioned above, there needs to be some convention by which items are made available to be auctioned on this platform. Current thinking is to follow the inspiration of ERC20, which describes fungible tokens and provides methods to find out an owner's balance, the transfer the token, and to allow others to transfer the token on your behalf up to a certain amount.

In the case of non-fungible assets, there is no concept of "balance", as each item is unique. Generally, a token is represented by an ID, and some associated metadata. An example (inspired from ERC137 which describes name records)...

contract NonFungible {
     struct Record {
          address owner;
          /* arbitrary metadata fields go here */
     }

     mapping(bytes32 => Record) records;    // Map an ID to the record

     modifier onlyOwner(bytes32 recordId) {
          if (records[recordId].owner != msg.sender) throw;
          _
     }

     function owner(bytes32 recordId) constant returns address {
          return records[recordId].owner;
     }

     function setOwner(bytes32 recordId, address newOwner) only_owner(recordId) {
          records[recordId].owner = newOwner;
     }
}

In this example each record has an owner identified by an address. There is a function for changing the owner, that only the current owner can call. This would facilitate the auction contract to set the owner as the auction contract during the create auction call (which would be initially called by the current owner). It would allow the auction contract itself to set the owner back to the original owner in the case of a failed auction, and to the new owner in the case of a successful one.

For now the contract works with Assets that implement the interface described in (Asset.sol)[blob/master/contracts/Asset.sol].

Dapp Frontend

This protocol is truly decentralized, requiring no authoritative central party, so it can exist entirely on chain via transactions. This means that many different types of frontends are possible. Initially, we provide an example frontend that will connect to a locally running ethereum node by default, or any ethereum network via the Metamask plugin.

The app is deployed centrally on AWS pointing at the Ropsten Testnet at [http://auction-house.s3-website-us-east-1.amazonaws.com/index.html].

The app is also deployed on IPFS, but that isn't reliable for upgrades at the moment since the hash will need to constantly be updated. When we go live on the mainnet, we will provide an IPFS hash to reference the reference frontend.


Questions

What is the best method for ensuring the underlying implementation of an Asset? It can implement the asset interface, but there's no guarantee that setOwner() actually transfers ownership. What does ownership even mean in the case of a one-off unique asset?

What other incentives besides the distributionCut would you like to see? Incentives for escrow, fraud detection, per-bid referrals?

Any security holes in the contracts? Right now this is in alpha and only on the testnet. I'm sure we'll discover flaws in the implementation before going live on mainnet.

Local Test Procedure

  1. Create local chain: geth --identity "ericnode" --rpc --rpcport "8081" --rpccorsdomain "*" --datadir ./chaindata --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 init ./CustomGenesis.json (create chaindata dir, then create CustomGenesis.json - http://ethdocs.org/en/latest/network/test-networks.html)
  2. Launch console: geth --identity "ericnode" --rpc --rpcport "8081" --rpccorsdomain "*" --datadir ./chaindata --port "30303" --nodiscover --rpcapi "db,eth,net,web3" --networkid 1999 console
  3. Create new account: personal.newAccount("password")
  4. Mine some ether: miner.setEtherbase(personal.listAccounts[0]); miner.start()
  5. Make sure miner is running when deploying to testnet
  6. Deploy contracts by running: truffle migrate
  7. Unlock account0: personal.unlockAccount(eth.accounts[0], "password")
  8. Run simple test: truffle test test/Simple.js

Note from Doug...I changed the launch command a bit to support only metamask calls and not calls from all external services.

./geth --identity "ericnode" --rpc --rpcport "8545" --rpccorsdomain "chrome-extension://idknbmbdnapjicclomlijcgfpikmndhd" --datadir ~/.chaindata/ --port "30303" --rpcapi "db,eth,net,web3,personal" --networkid 1999 console