Now we see the buyer address (Bob’s) recorded, and this item is marked as true (sold).
Step 4: Alice tries to remove this item. She cannot as this item was sold already.
Phase 2: Marketplace with Token as Payment Methods
Create a New Workspace
With the basic functions of marketplace ready, we will now include an ERC20 as the pricing and payment method for this marketplace.
To keep things neat, here we create another workspace, namely emarketwithcoin
mkdir emarketwithcoin
cd emarketwithcoin
dapp init
We are using ds-token package provided in dapp.tools. ds-token is a package of standard ERC20 implementation, plus some additional functions like mint() and burn(). There are some advanced features working with other packages but the basic ERC20 and the mint/burn are good enough for our demonstration.
We will first install the package.
dapp install ds-token
All the required packages required are installed. The package is installed under lib/ds-.
If we inspect the contracts in lib/ds-/src/base.sol and lib/ds-/src/.sol, we probably see an implementation of ERC20 , and some additional functions. Meanwhile each comes with a unit test contract, and the test are running when the contract is deployed.
Modify Our Contract Code
For simplicity, we only focus on the contract code, and put aside the testing contract code (we see how it works in early sessions). It is not the best practice as we should always use testing contract for unit testing. Nevertheless, we assume our code are good for demonstration.
Here is the contract code for Emarketwithcoin.
Here I just highlight the additional portion on top of the previous example.
1. Import the contract from the ds-token package. Here we import .sol.
import “ds-token/token.sol”;
If we take a look on the code, .sol further imports base.sol. And .sol provides the class DSToken that we will use later. Note the default DSToken comes without a fixed supply and with decimal precision 18. For demonstration purpose we will keep this without considering the actual precision.
2. Specify where the contract is.
ERC20 public emark;
constructor (address _emark) public
Here we define an object emark, which holds the deployed contract. As a result, in our deployment we first deploy a contract, and the contract ID of the deployed contract is passed to this contract through constructor. We will see how it works later.
3. Transfer when buy an item.
function buyItem(uint _index) public
We add two logics here. First we will check buyer’s balance when he buys a listed item. If balance is not enough the transaction fails. Also we will use transferFrom to transfer from someone who buys this item to the seller of this item. Since it is the Emarketwithcoin contract performs the transferFrom, the buyer needs to approve the Emarketwithcoin contract for the transfer. We will see how it works later.
4. Update the test contract (inside Emarketwithcoin.t.sol).
function setUp() public
As we have included constructor and an address is required, we need to modify the Emarketwithcoin.t.sol with a pseudo address for getting through the test. Again we are not defining any test cases and therefore the test address is not meaningful in this case.
Deploy Contracts in Testnet
As before, we open another terminal to run a testnet, using dapp testnet. We also needs two more addresses for demonstration.
We will create the environment variables for demonstration purpose. The first one we use ETH_FROM such that it is the account. If we do not specify anything it is the default account.
export ETH_KEYSTORE=~/.dapp/testnet/8545/keystore
export ETH_GAS=3000000
export ETH_FROM=0x631911a584ae91af67efce2adb3d20b5e29b3be5
export ALICE=0x2963cb08f690a072b718addbc6478641305f5e69
export BOB=0x486e85148d38402bd72a30fea6dcbc7a5cb5f3d8
Now we deploy the contract first. The symbol we pass to the new contract is emark.
dapp create DSToken $(seth —-to-bytes32 $(seth —-from-ascii emark))
Now we have the contract ID (or contract address). We will use an environment variable EMK to hold this address.
export EMK=0xce13f923964091acb55c4c8fcf5b6f2a3261dda6
With this, we can deploy the Emarketwithcoin contract. We specify the contract ID as required in constructor.
dapp create eMarketwithcoin $EMK
Now we have another contract ID. We will hold this in environment variable MARKET.
export MARKET=0xda99912a9c7a370cd24621f0147f4b13e1d0f830
Now we have both contracts deployed.
Interacting with the Contracts
Our demonstration flow on these deployed contract is simple.
- Check emark balance of both Alice and Bob, and see no balance at the beginning.
- Mint Bob 100 emarks. It will be used for buying an item listed by Alice.
- Alice lists an item with price set to 80 emarks.
- Bob buys this item.
- Check emark balance of both Alice and Bob, and we see 80 emarks transferred to Alice.
Always remember we have two contracts: EMK for , and MARKET for marketplace. They are two independent contracts, and the only linkage is that MARKET contract will call EMK when someone buys items.
Step 1: We begin with contract. Check balance of total EMK supply, and balances of Alice and Bob.
seth call $EMK “totalSupply()”
seth call $EMK “balanceOf(address)” $ALICE
seth call $EMK “balanceOf(address)” $BOB
Initially all are zero. No emark exists yet.
Step 2: We mint 100 emarks to Bob.
seth send $EMK “mint(address,uint)” $BOB $(seth —-to-uint256 100)
And check the balance. Bob has 100 emarks (0x64) and total emark supply is also 100.
Before MARKET can transfer from Bob’s account, Bob needs to approve MARKET that amount. Assuming Bob approves 80 emarks.
seth send $EMK “approve(address,uint)” $MARKET $(seth —-to-uint256 80) —-from=$BOB
Step 3: We move to the marketplace. Alice lists an item “a pen” and the price is 80 emarks.
seth send $MARKET “addItem(string memory, uint)” $(seth —-from-ascii “a pen”) $(seth —-to-uint256 80) —-from=$ALICE
And we will see the item #1 recorded.
seth call $MARKET “items(uint)(string memory,address,address,uint,bool)” $(seth —-to-uint256 1)
Item is listed by Alice and now sold yet.
Step 4: Bob is buying this item.
seth send $MARKET “buyItem(uint)” $(seth —-to-uint256 1) —-from=$BOB
And we check the item #1 again.
seth call $MARKET “items(uint)(string memory,address,address,uint,bool)” $(seth —-to-uint256 1)
The item is sold to Bob.
Step 5: Finally we check the total EMK supply and balance of both Alice and Bob again.
We see 80 emarks is transferred from Bob to Alice as Bob has bought Alice’s item with 80 emarks. And the total supply remains 100 emarks.
Closing
We have shown a sample marketplace contract (again, not optimized one and not for production). We saw how to use test contract to implement some unit tests on the functions. After deploying on the testnet, we demonstrate how to execute the functions defined in the marketplace. Then we use the same marketplace contract and add as the pricing and payment method. Using ds- package and with a few modifications, the marketplace contract can perform the transfer when a buying is made.
Hope you can see the use of dapp.tools and the convenience when developing contract on platform. There are some other packages from dapp.tools and you will find more fun from them.
Published at Sun, 19 May 2019 03:14:26 +0000