How to Build Nebulas Dapps Tutorials: Part 1

decentralized apps nebulas smart contracts dapps nameledger

In the previous post we talked about the problem NameLedger is trying to solve. In this post we will take a detailed look at the smart contract itself.

Workflow

Lets start by looking at th on chain storage data

var NameLedger = function () {
  LocalContractStorage.defineProperties(this, {
        owner: null,
        balance: null,
        name_count: null
  });
  LocalContractStorage.defineMapProperty(this, "namemap");
  LocalContractStorage.defineMapProperty(this, "addrmap");
  LocalContractStorage.defineMapProperty(this, "bids");
};

In our case we will have owner to save the owner of the smart contract, balance to store the balance amount, name_count to find the number of registeredNames

reserveName: function (name) {
    name = name.toLowerCase();
    var from = Blockchain.transaction.from;
    var value = Blockchain.transaction.value;
    var amount = new BigNumber(value);
    var cost = (this.name_count < 50) ? 0 : 0.1;
    if (amount < new BigNumber(cost)) {
      throw new Error("You need to send 0.1 NAS with the transaction to reserve your name. \
        Think of this as buying a domain name." );
    }

    if (amount >  new BigNumber(0)) {
      amount = amount.plus(this.balance);
    }
    this.namemap.put(name, from);
    this.addrmap.put(from, name);
    this.bids.put(name, -1);
    this.balance = amount;
    this.name_count = new BigNumber(1).plus(this.name_count);
  }

For reserveName we want people to pay 0.1 NAS just so that we can make sure people don’t abuse the service and don’t register each and every name.

One interesting fact about this method is that we are providing some bounty when reserving name. So the first 50 names reserved don’t need to pay 0.1NAS so make sure you register your name at Register your name.

Also if they send less than 0.1 NAS we throw an error. Next we will update the balance. Add the name to namemap name->address and addr->name. By default the name is not up for sale. We signify this by setting it to -1. We also update the total names registered in name_count.

Now lets look at the currentBid method which doesn’t do anything fancy just lookup the name in the bids map and return the value.

  currentBid: function(name) {
    name = name.toLowerCase();
    this._validate(Blockchain.transaction.value);
    if (this.namemap.get(name) == null) {
      throw new Error("Domain is still available");
    }

    if (this.bids.get(name) == -1) {
      return "Not available for sale";
    } else {
      return this._toNas(this.bids.get(name))+" NAS";
    }
  }

setBid is where we set the bid for a name in NAS when we decide to sell or transfer the ownership of a name to someone else. For example lets say you own a name seoexperts and some time in future a seo agency is interested in buying the name it could do so by paying the necessary bid set by you.

setBid: function(name, value) {
name = name.toLowerCase();
this._validate(Blockchain.transaction.value);
if (this.namemap.get(name) !== Blockchain.transaction.from) {
  throw new Error("You don't own the name");
}
var new_bid = this._toWei(value);
this.bids.put(name, new_bid);
return this._toNas(new_bid);
}

Now lets look at the transferName which is used when transferring the name.

  transferName: function(name) {
    name = name.toLowerCase();
    var value = Blockchain.transaction.value;
    var amount = new BigNumber(value);

    if (this.bids.get(name) === new BigNumber(-1)) {
      throw new Error(name + " is not for sale");
    }

    if (amount < this.bids.get(name)) {
      throw new Error("You sent less NAS than what they asked for. Current bid for the name is : " + this._toNas(this.bids.get(name)));
    }

    var current_owner = this.namemap.get(name);

    // Current transaction fees is 0.1%

    var tx_fee = amount.times(0.001)
    // Pay transaction fee to the contract
    var result = Blockchain.transfer(this.owner, tx_fee);
    if (!result) {
      throw new Error("Couldn't pay transaction fee");
    }

    amount = amount.minus(tx_fee)
    var result = Blockchain.transfer(current_owner, amount);
    if (!result) {
      throw new Error("transfer failed. " + current_owner + " " + amount +" " + this._toNas(amount));
    }
    this.namemap.put(name, Blockchain.transaction.from);
    this.addrmap.put(Blockchain.transaction.from, name);
    this.bids.put(name, -1);
  }

Steps for the transfer name

That’s it for this blog post. Please let me know if you have any feedback or anything else you would want to know. Also if you want to get started make sure you start building app on the platform.

Comments

comments powered by Disqus