人生的第一桶金 —— Nebulas DApp 開發從零開始

前言

5月7日 00:00 - 7月2日 00:00,Nebulas(星雲) 有一個激勵計劃,開發DApp, 最高月度優秀獎勵可達 20000 NAS 價值約 120w RMBhtml

人生的第一個一百萬,第一桶金,興不興奮, 心不心動!!~ 無論你心不心動, 反正我心動了!前端

第一步確定是先註冊一個帳號了, 註冊連接java

好了,看到錢就興奮不算一件壞事,不過還須要冷靜下,這120w 不是這麼好拿的,不過對於普通的開發者來講 還有一個很大的福利, 只要你成功上架一個DApp,便可得到 100 NAS 價值 6000 RMB 這都我等來講 也算一筆不大不小的收入, 若是寫的優秀點的話,還有更多的獎項在等着,就算拿不到 120w,努力點 那個幾萬 甚至十幾 二十萬 仍是有可能的。具體能夠查看官網說明node

ps. 固然官方對幫忙推廣宣傳的,也有必定的獎勵,若是小夥伴們經過我上面的邀請連接進入的,而且成功上架一個DApp的話 我也是能獲取到 40 NAS,固然你本身自己的獎勵不會減小(據社區小夥伴透露,經過別人邀請連接進入的,成功上架一個DApp 的獎勵上升到110 NASgit

準備工做

前言打了一波雞血, 120w 想拿到,怎麼說都要成功上架一個 DApp以後,纔有這個機會。講一下準備工做吧。github

  1. 首先你得會 JavaScript(TypeScript 也行),不會的小夥伴 自行學習下。
  2. 其次你得了解下 DApp 是個什麼東西?
  3. 開發流程是怎麼樣的?怎麼部署以及發佈?
  4. 去哪裏提交上架?

DApp 是個什麼東西?

其實建議自行 google 百度下,會清楚點,在這裏我作個簡單的介紹,本身的理解,可能有所出處。web

DApp 即 decentralized application (去中心化應用),主要是至關於中心化應用來講的。目前的App來講,基本上都是中心化應用,有中心化的服務器,數據存儲讀取都是跟中心化服務器作交互。而去中心化應用,去掉的就是中心化的服務器,才用的是區塊鏈的去中心化的數據庫。chrome

最先應該是以太坊提出智能合約以後纔出來的一個概念,至於智能合約,我的理解是至關於後端,數據經過智能合約存儲在區塊鏈上。數據庫

開發流程

重頭戲來了,基友星雲鏈開發一個DApp的流程是怎麼樣的npm

  1. 先去星雲官網註冊帳號,註冊連接
  2. 下載官方web錢包, 並使用該web錢包建立咱們本身的錢包
  3. 下載官方Chrome插件,github上有教程
  4. 開發智能合約,(本文會採用官方推薦的最簡單的一個例子)
  5. 部署智能合約,(部署合約的時候須要少許的NAS, 測試鏈上的幣能夠在這裏領取,正式鏈上的NAS,若是沒有渠道的話,能夠聯繫我微信 xuanyuan_1, 備註請按 掘金-DApp-你的名字, 若是你是按個人邀請連接註冊的我將免費送你一點NAS幣 用於部署智能合約。)
  6. 開發Web前端界面
  7. 部署前端界面(這塊不熟悉的,或者沒有域名的,也能夠聯繫我)
  8. 提交DApp(坐等拿錢)

ps. 拿到手的是NAS,若是不想持有直接提現的話,能夠去火幣等交易所提現

本文會主要講一下智能合約,以及web前端開發兩個部分。

智能合約

若是沒有智能合約這個概念的話,能夠把這塊理解後端的接口。星雲的智能合約是基於 Chrome 的 V8 引擎開發的,支持 JavaScriptTypeScript。 智能合約的執行模型以下:

內置了一下 LocalContractStorage 模板來提供存儲功能, BigNumber 模塊進行數值的處理, Blockchain 對象能夠取得當前合約所在的塊和Transaction信息... 具體能夠參考 官方的文檔

寫智能合約

直接上代碼

"use strict";

var DictItem = function(text) {
  if (text) {
    var obj = JSON.parse(text);
    this.key = obj.key;
    this.value = obj.value;
    this.author = obj.author;
  } else {
    this.key = "";
    this.author = "";
    this.value = "";
  }
};

DictItem.prototype = {
  toString: function () {
    return JSON.stringify(this);
  }
};

var SuperDictionary = function () {
  LocalContractStorage.defineMapProperty(this, "repo", {
    parse: function (text) {
      return new DictItem(text);
    },
    stringify: function (o) {
      return o.toString();
    }
  });
};

SuperDictionary.prototype = {
  init: function () {
    // todo
  },

  save: function (key, value) {
    key = key.trim();
    value = value.trim();
    if (key === "" || value === ""){
        throw new Error("empty key / value");
    }
    if (value.length > 64 || key.length > 64){
        throw new Error("key / value exceed limit length")
    }

    var from = Blockchain.transaction.from;
    var dictItem = this.repo.get(key);
    if (dictItem){
        throw new Error("value has been occupied");
    }

    dictItem = new DictItem();
    dictItem.author = from;
    dictItem.key = key;
    dictItem.value = value;

    this.repo.put(key, dictItem);
  },

  get: function (key) {
    key = key.trim();
    if ( key === "" ) {
      throw new Error("empty key")
    }
    return this.repo.get(key);
  }
};
module.exports = SuperDictionary;
複製代碼

上面的智能合約就是就是官方demo裏的,吐槽一下寫這個demo的人 多是以前寫 java 的或者是強行把 TypeScript 擼成 JavaScript。

完成能夠改寫成下方形式, (爲了節省篇幅把說明直接寫在註釋裏了)

// 構建一個SuperDictionary 類 ES5的寫法 能夠用ES6 class的寫法也行
var SuperDictionary = function () {
  LocalContractStorage.defineMapProperty(this, "repo");
};

SuperDictionary.prototype = {
  // 這個方法比較有,初始化合約的時候 作相應的處理, 好比說 初始化的時候 綁定直接是用戶
  init: function () {
    // todo
  },
  /** * 保存內容 * key: 關鍵字 * vlaue: 關鍵字所對應的定義 */
  save: function (key, value) {
    key = key.trim();
    value = value.trim();
    if (key === "" || value === ""){
        throw new Error("empty key / value");
    }
    if (value.length > 64 || key.length > 64){
        throw new Error("key / value exceed limit length")
    }
    /** * Blockchain.transaction.from 即本次請求的區塊鏈地址 */
    var from = Blockchain.transaction.from;
    var dictItem = this.repo.get(key);
    // 若已經存在 則這個詞已經被搶注了 拋出異常
    if (dictItem){
        throw new Error("value has been occupied");
    }
    // 很自信的以爲 下面的寫法是對的 沒想到測試沒經過 可怕
    // dictItem = {
    // author: from
    // key,
    // value
    // }
    // 最後改爲以下寫法
    dictItem = {};
    dictItem.author = from;
    dictItem.key = key;
    dictItem.value = value;
    // 保存
    this.repo.put(key, dictItem);
  },
  // 獲取相關保存的詞
  get: function (key) {
    key = key.trim();
    if ( key === "" ) {
      throw new Error("empty key")
    }
    return this.repo.get(key);
  }
};
module.exports = SuperDictionary;
複製代碼

這個DApp要實現的什麼功能,其實看合約 就知道了。這是一個名爲 SuperDictionary 的DApp, 主要實現的功能即爲能夠在這個 DApp 查詢一個詞,若這個詞沒有被人搶注,你就能夠本身註冊下(好比說 搜個人大名 Duke 基本上不會有人註冊,我給它一個定義 世上最帥的人,那麼這條信息就將永久保存在星雲鏈上,別人再使用這個DApp 查詢 Duke 能夠看到 我給他下的定義。)

星雲鏈的智能合約有三點簡要的規範:

  1. 智能合約代碼必須是一個Prototype的對象;
  2. 智能合約代碼必須有一個init()的方法,這個方法只會在部署的時候被執行一次;
  3. 智能合約裏面的私有方法是以_開頭的方法,私有方法不能被外部直接調用;

部署智能合約

部署智能合約有三步

  1. 檢查你的帳戶的狀態
  2. 若帳戶裏有足夠的錢來支付手續費則開始解鎖帳戶(解鎖時間爲12小時)
  3. 再解鎖的期間 發送部署BankVault合約的交易

詳情可查看這裏

這三步都須要發一個請求出去,並且例子上的地址是 localhost 意味着 你還須要編譯安裝一個星雲鏈的代碼,至關於成爲星雲鏈的一個節點。 so trouble!!! 我只是想安靜的擼一個 DApp, 這些是什麼鬼!!!

別擔憂我有招(其實官方也考慮到這點了)

到官方github 把 web版錢包 下載下來,npm install 安裝依賴,再 node server.js 運行服務。再接下來在瀏覽器中輸入 http://localhost:8080/ 便可看到以下界面

這樣咱們就部署成功了,到此爲止咱們就基本上完成了,DApp後端部分的工做,咱們能夠開始愉快的擼前端界面了。

ps. 開發的時候,咱們最好用的是測試鏈,測試鏈上的幣能夠在這裏領取,可是提交

前端界面

基本上的界面,你們就自我發揮吧。主要來說一下會遇到的坑點。怎麼調用

官方提供了一個方法 nebPay, 可是官方並無把他提交到npm上去,有點憂傷,只能本身動手 佔個坑, 直接可使用 npm install nebpay 就能夠下載

最開始本身傻逼了,覺得只能上傳到npm上才能用,後來發如今 package.json 直接寫 "${name}":"git+${it's github url}"也行,拿nebPay舉例即爲"nebpay": "git+https://github.com/nebulasio/nebPay"

api 調用

前面講了前端調用合約的方式,具體代碼怎麼寫呢,我簡單的封裝了下,你們能夠作個參考

import NebPay from 'nebpay'
const nebPay = new NebPay()
/** * * @param {String} callFunction 調用合約的方法 * @param {Array} param 請求的參數 * @param {Boolean} needPay 是否須要支付 */
const api = function (callFunction, param = [], needPay = false) {
  return new Promise((resolve, reject) => {
    const to = dappAddress
    const value = '0'
    const callArgs = JSON.stringify(param)
    /** * 若是隻查詢類的請求 就不須要去支付 直接使用 nebPay 的 simulateCall 便可 * 若是不是查詢類的 須要調用支付接口 使用 nebPay 的 call 調用 */
    const way = needPay ? 'call' : 'simulateCall'
    nebPay[way](to, value, callFunction, callArgs, {
      listener: (res) => {
        console.log('listener', res)
        try {
          resolve(JSON.parse(res.result))
        } catch (e) {
          reject(res.result)
        }
      }
    })
  })
}
複製代碼

顯而易見,只要用到了兩個方法,callsimulateCall, 二者的在因而否須要修改合約裏的內容。好比查詢類的就想咱們的合約裏的 get 方法,咱們就用 simulateCall, 可是如咱們合約裏的 save 方法就須要使用 call,會調用 nebulas 的 chrome 錢包插件,須要支付少許的礦工費,這樣咱們才能把咱們的信息永久保存在星雲鏈上。

結語

一不當心囉囉嗦嗦了,寫了一堆,不知道對小夥伴們,有沒有幫助。今天(2018-05-21)已是激勵計劃的第三週了,基本上簡單的應用都被人佔坑了,若是想要過審覈,須要多一點點創意,多一點點功能把 DApp 作的稍微飽滿點, 單人閉門造車已經很難了,有興趣的或者有好想法的小夥伴,一塊兒組個隊一塊兒玩,後續的機會仍是有的。真獲獎了獎勵平分。 我微信及手機號爲: MTg5MDY3Nzc1NzM= (加微信就好 ^_^ 請備註 掘金)


發了這篇文章以後 有很多人找我。發幾個幣給我玩玩唄。 我感受仍是有必要說明下: 部署合約須要正式鏈上的 NAS, 須要的很是少,連一分錢都不到,因此我在前面提到送一些NAS,只是爲開發所需(畢竟經過交易所什麼的來即麻煩又費時費錢)。我並非土豪,抱有其餘目的的小夥伴 能夠無視我了!

相關文章
相關標籤/搜索