2

The Golem Network Token (GNT) TokenTrader contracts enables the trustless and decentralised sale of GNTs for ethers (ETH).

A seller deploys one of these TokenTrader contracts using the TokenTraderFactory.createTradeContract(...) method, specifying the rate at which they want to sell their GNTs, then top up the contract with GNTs. Instructions from the original author can be found here.

A buyer simply sends ETHs to the seller's deployed TokenTrader contract and will receive the GNTs back in the buyer's address.

Further information can be found on https://www.bokconsulting.com.au/blog/trustless-token-selling-contract/ and https://www.reddit.com/r/ethtrader/comments/5cnl58/trustless_gnt_selling_contract/ .

How do I find the list of TokenTrader contracts?

1 Answer 1

2

Update Nov 17 2016

Live updating list of contracts are now available at https://cryptoderivatives.market/.



You can find the following script at https://github.com/bokkypoobah/FindGNTTokenTrader/blob/master/findGNTTokenTrader .

#!/bin/sh

# ------------------------------------------------------------------------------
# Find Golem Network Token (GNT) Token Trader information
# 
# Works on Linux and OS/X. May work on Windows with Cygwin.
#
# Usage:
#   1. Download this script to findGNTTokenTrader
#   2. `chmod 700 findGNTTokenTrader`
#   3. Run `geth console` in a window.
#   4. Then run this script `./findGNTTokenTrader` in a separate window.
#
# More information:
#   * https://www.bokconsulting.com.au/blog/trustless-token-selling-contract/
#   * https://www.reddit.com/r/ethtrader/comments/5cnl58/trustless_gnt_selling_contract/
#
# Notes:
#   * This scripts list all deployed TokenTrader, even those deployed with some
#     errors. The Sell price and Units fields for the TokenTrade deployed
#     with errors is normally crazily incorrect
#   * If you do want to try purchasing GNTs from these contracts, test with
#     a small amount first
#
# History:
#   * Nov 14 2016 - Version 1.0
#   * Nov 14 2016 - Version 1.01 - With bookid feedback from /u/JonnyLatte
#   * Nov 14 2016 - Version 1.02 - Getting correct token balance for the 
#                                  TokenTrader contract
#   * Nov 15 2016 - Version 1.03 - Tidy
#   * Nov 15 2016 - Version 1.04 - Getting correct ether balance for the
#                                  TokenTrader contract
#   * Nov 16 2016 - Version 1.05 - CSV and filters
#
# Enjoy. (c) BokkyPooBah 2016. The MIT licence.
# ------------------------------------------------------------------------------

DATETIME=`date -u "+%Y%m%d_%H%M%S%Z"`
TMPFILENAME="/tmp/findGNTTokenTrader.txt";
TXTFILENAME="findGNTTokenTraderOutput_${DATETIME}.txt"
CSVFILENAME="findGNTTokenTraderOutput_${DATETIME}.csv";

geth attach << EOF > $TMPFILENAME

var gntTokenTraderFactoryDeploymentBlock = 2615848;
var gntTokenTraderFactoryAddress = "0xC4aF56cD5254Aef959D4BcE2F75874007808b701";
var gntBookId = "0x2fd64880bc17977672b2e25fff32b433975c4004b4fbd094936429e92f58d39f";
var gntTokenTraderFactoryABI = [{"constant":false,"inputs":[{"name":"_asset","type":"address"},{"name":"_sellPrice","type":"uint256"},{"name":"_units","type":"uint256"},{"name":"_sellsTokens","type":"bool"}],"name":"createTradeContract","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"tradeContract","type":"address"}],"name":"verify","outputs":[{"name":"valid","type":"bool"},{"name":"asset","type":"address"},{"name":"sellPrice","type":"uint256"},{"name":"units","type":"uint256"},{"name":"sellsTokens","type":"bool"}],"payable":false,"type":"function"},{"payable":false,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"bookid","type":"bytes32"},{"indexed":false,"name":"owner","type":"address"},{"indexed":false,"name":"addr","type":"address"}],"name":"TradeListing","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"bookid","type":"bytes32"},{"indexed":false,"name":"asset","type":"address"},{"indexed":false,"name":"units","type":"uint256"}],"name":"NewBook","type":"event"}];
var gntTokenTraderABI = [{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"withdraw","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"asset","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"sellPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"sellsTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_value","type":"uint256"}],"name":"withdrawAsset","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"units","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"_token","type":"address"},{"name":"_value","type":"uint256"}],"name":"withdrawToken","outputs":[{"name":"ok","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"buy","outputs":[],"payable":true,"type":"function"},{"constant":false,"inputs":[{"name":"_sellsTokens","type":"bool"}],"name":"activate","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"type":"function"},{"inputs":[{"name":"_asset","type":"address"},{"name":"_sellPrice","type":"uint256"},{"name":"_units","type":"uint256"},{"name":"_sellsTokens","type":"bool"}],"type":"constructor"},{"payable":true,"type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sells","type":"bool"}],"name":"ActivatedEvent","type":"event"},{"anonymous":false,"inputs":[],"name":"UpdateEvent","type":"event"}];
var gntTokenABIFragment = [{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"}];
var erc20ABIFragment = [{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"type":"function"}];
var minimumSellPrice = 0.0001;
var maximumSellPrice = 100000000;

var gntTokenTraderFactoryInterface = web3.eth.contract(gntTokenTraderFactoryABI).at(gntTokenTraderFactoryAddress);
var tradeListingEvent = gntTokenTraderFactoryInterface.TradeListing({valueA: gntBookId}, {fromBlock: gntTokenTraderFactoryDeploymentBlock, toBlock: 'latest'});
var i = 0;
var now = new Date();
console.log("Data: Listing generated at " + now.toUTCString()); 
console.log("CSV: #,TokenTraderAddress,SellsTokens,EtherPer1000Tokens,TokenBalance,Block,Deployed,TxHash,Owner,Asset,Symbol,SellPrice,Units," +
  "TokenTraderEtherBalance,OwnerEtherBalance");  
tradeListingEvent.watch(function (error, result) {
    try {
      var tokenTrader = web3.eth.contract(gntTokenTraderABI).at(result.args.addr);
      var assetAddress = tokenTrader.asset();
      var sellPrice = tokenTrader.sellPrice();
      if ("0xa74476443119a942de498590fe1f2454d7d4ac0d" == assetAddress &&
          sellPrice >= minimumSellPrice &&
          sellPrice <= maximumSellPrice) {
        console.log("Data: " + i + " TokenTrader Address: " + result.args.addr);
        var block = eth.getBlock(result.blockNumber);
        var deployedAt = new Date(block.timestamp * 1000);
        console.log("Data:   Deployed                         : #" + result.blockNumber + " at " + deployedAt.toUTCString());
        console.log("Data:   TxHash                           : " + result.transactionHash);
        console.log("Data:   Owner                            : " + result.args.owner);
        var ercInterface = web3.eth.contract(erc20ABIFragment).at(assetAddress);
        var symbol;
        try {
          symbol = ercInterface.symbol();
        } catch (e) {
          symbol = "???";
        }
        console.log("Data:   Asset address                    : " + assetAddress + " " + symbol);
        var sellsTokens = tokenTrader.sellsTokens();
        console.log("Data:   Sells tokens                     : " + sellsTokens);
        console.log("Data:   Sell price                       : " + sellPrice);
        var units = tokenTrader.units();
        console.log("Data:   Units                            : " + units);
        console.log("Data:   Ethers per 1,000 tokens          : " + sellPrice.div(units).mul(1000));
        var asset = web3.eth.contract(gntTokenABIFragment).at(assetAddress);
        // Does not work
        // var originalTokenBalance = asset.balanceOf(result.args.addr, result.blockNumber);
        // console.log("Data:   Tokens balance at creation    : " + originalTokenBalance.div(1e18));
        var tokenBalance = asset.balanceOf(result.args.addr);
        console.log("Data:   Current TokenTrader token balance: " + tokenBalance.div(1e18));
        var tokenTraderEtherBalance = eth.getBalance(result.args.addr);
        console.log("Data:   Current TokenTrader ether balance: " + tokenTraderEtherBalance.div(1e18));
        var ownerEtherBalance = eth.getBalance(result.args.owner);
        console.log("Data:   Current Owner ether balance      : " + ownerEtherBalance.div(1e18));
      
        // var updateEvent = tokenTrader.UpdateEvent({}, {fromBlock: result.blockNumber, toBlock: 'latest'});
        // updateEvent.watch(function (error1, result1) {
        //   console.log("    " + JSON.stringify(result1));
        // });
        // updateEvent.stopWatching();
        console.log("CSV: " + i + "," + result.args.addr + "," + sellsTokens + "," + 
          sellPrice.div(units).mul(1000) + "," + tokenBalance.div(1e18) + "," + 
          result.blockNumber + "," + deployedAt.toUTCString() + "," + 
          result.transactionHash + "," + result.args.owner + "," + 
          assetAddress + "," + symbol + "," + sellPrice + "," + units + "," +           
          tokenTraderEtherBalance.div(1e18) + "," + ownerEtherBalance.div(1e18));
        console.log(i++ + ": " + JSON.stringify(result));
      }
    } catch (e) {
      console.log("Data:   Cannot get details for TokenTrader " + e);
    }
});
tradeListingEvent.stopWatching();

EOF

grep "Data:" $TMPFILENAME | sed "s/Data: //" > $TXTFILENAME
grep "CSV:" $TMPFILENAME | sed "s/CSV: //" | grep -v "false" > $CSVFILENAME

Notes

  • This scripts list all deployed TokenTrader, even those deployed with some errors. The Sell price and Units fields for the TokenTrade deployed with errors is normally crazily incorrect.
  • If you do want to try purchasing GNTs from these contracts, test with a small amount first.
  • This is just a tool for finding the contracts. Your use of the contracts is your own responsibility!

The latest listing in tabular format https://github.com/bokkypoobah/FindGNTTokenTrader/blob/master/findGNTTokenTraderOutput_20161115_200640UTC.csv, with the active market below:

#,TokenTraderAddress,SellsTokens,EtherPer1000Tokens,TokenBalance
26,0x4b17f65fc6450cbcced9e893dd84123a5fc13362,TRUE,1.45,154913.0693
27,0x1e00980cb7b109d290fcf6c4e579debb8c836c39,TRUE,1.45,329983.1034
24,0x1a22bb6827dbb7df60a6de726519c2a509271695,TRUE,1.5,580393.55
6,0xc0081f0e16cbceec6df8e63986212a52ee493540,TRUE,1.88,102821.2909
23,0x406a65de7a2e94ef19597a79296e269fada85a71,TRUE,1.9,136166.8742
15,0x5eb860c816789bb52300a0675300701eca203cf8,TRUE,1.95,158854.1026
0,0x399156ee3339f4b29a53e307b98cce09fda3bac7,TRUE,2,5430.015
10,0xa7f8da2594eaf1e8573a5974be6028f64157cd7a,TRUE,2,713516
22,0xf31057bc0ff5e3e3b32652b29c0451624392567c,TRUE,2,100050
25,0xffd41efe3d3c073f4c7dbf2cec7c19111fc7523e,TRUE,2,4250
17,0x6e3f7ad4d9accb12452744fb2785ecac31ea8026,TRUE,2.05,50000
18,0x4b34da26bfb35d3089c455cb483a5fff8695d447,TRUE,2.11,200000
11,0x42be3b481f25b0148cd1a144d8ca22cda5b677e7,TRUE,2.33,9.00E-12
2,0x4104e4b12e73bc99dd4f20a39525d07aa395c0d4,TRUE,3,1794.833333
19,0x593fd4a14f64282891a1369442462361a1908b01,TRUE,3.75,900

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.