7*24快訊學習如何創...

學習如何創建自己的加密貨幣l Chainlink 博客

貨幣是商品和服務的交換媒介。如今,貨幣採用紙幣、硬幣或集中式數字分類賬的形式,通常由政府發行並被普遍接受為一種支付方式。過去,貨幣以各種金屬的形式出現,如金銀,甚至是彩色珠子和鹽。加密貨幣是一種以密碼學和區塊鏈技術為基礎的數字貨幣形式,主要用作轉移價值的一種方式,而無需依賴單一的中心化平台,例如銀行。

在本技術教程中,我們將探討硬幣和代幣之間的區別,您將學習如何開發自己的加密硬幣。

讓我們開始吧!

硬幣和代幣的區別

比特幣是最流行的加密貨幣,其主要目的是作為一種交換媒介。還有許多代幣具有價值,但除了作為一種交換形式的效用之外,還有其他用途:例如,治理投票代幣授予持有人某些治理特權。還有NFT:代表獨特事物所有權的不可替代代幣。那麼,所有這些類型的數字資產之間有什麼區別?

從工程的角度來看,硬幣和代幣之間的區別非常簡單。硬幣是單個區塊鏈的一部分,而代幣以智能合約的形式在現有區塊鏈上運行。

例如,BTC 是比特幣區塊鏈的幣,ETH 是以太坊區塊鏈的幣。 BTC 和ETH 都是硬幣。僅舉幾個例子,USDC、AAVE 和WETH 都是代幣,因為它們本質上是託管在以太坊區塊鏈之上的智能合約。同樣的原則也適用於NFT:它們也是駐留在各種通用區塊鏈上的代幣。

要了解如何創建自己的令牌,請查看 這篇博文。 要了解有關創建NFT 的更多信息,請查看 本指南. 繼續閱讀以了解有關創建自己的加密貨幣的更多信息。

入門

這個項目是用Go 編寫的,但不需要以前有這種語言的經驗。要繼續,請查看位於 Chainlink 智能合約示例存儲庫 在我的加密硬幣文件夾下。

git clone https://github.com/smartcontractkit/smart-contract-examples.git
cd smart-contract-examples/my-crypto-coin

下一步是在本地機器上安裝Go,您可以按照官方指南進行操作。由於此過程大約需要10 分鐘,因此您將有時間在完成後煮咖啡。

驗證您的 $GOPATH 在繼續之前正確設置。這是一個強制性步驟。

約定是將源代碼存儲在 $GOPATH/src 和里面的編譯程序二進製文件 $GOPATH/bin. 導航到 $GOPATH/src 並創建一個名為 my-crypto-coin.

讓我們從開發開始。

一切從創世區塊開始

硬幣是區塊鏈分佈式賬本中的單位。每個區塊鏈都有其初始狀態,也稱為創世塊。在你新創建的里面 my-crypto-coin 項目,創建一個新文件夾並命名 ledger. 在- 的里面 ledger 文件夾,新建一個文件,命名 genesis.json,然後粘貼下面的代碼。我們將分配給Alice 最初的100 萬份我們的加密貨幣。

{
  "genesis_time": "2022-04-12T00:00:00.000000000Z",
  "chain_id": "our-blockchain",
  "balances": {
    "alice": 1000000
  }
}

這是原始狀態。事務改變狀態。如果我們的區塊鏈節點出現故障,我們可以使用創世文件和交易歷史來重新創建整個分類帳並將網絡的其餘部分同步到最新狀態。

賬戶、交易和全局狀態

導航到 ledger 文件夾並創建一個 tx.go 文件。每個帳戶將由帳戶結構表示。每個事務將由事務結構表示,具有以下屬性:“from”、“to”和“value”。我們將添加一個用於創建新帳戶和交易的功能。

package ledger

type Account string

type Tx struct {
     From  Account `json:"from"`
     To    Account `json:"to"`
     Value uint    `json:"value"`
}

func NewAccount(value string) Account {
     return Account(value)
}

func NewTx(from Account, to Account, value uint) Tx {
     return Tx{from, to, value}
}

交易將存儲在分類帳中,所以讓我們手動添加幾個作為演示。在- 的里面 ledger 目錄,新建一個 ledger.db 文件並在那裡粘貼以下內容。

{"from":"alice","to":"bob","value":10}
{"from":"alice","to":"alice","value":3}
{"from":"alice","to":"alice","value":500}
{"from":"alice","to":"bob","value":100}
{"from":"bob","to":"alice","value":5}
{"from":"bob","to":"carol","value":10}

創世狀態保持不變並保持在 genesis.json 文件。讓我們添加一種以編程方式加載其狀態的方法。創建一個名為的新文件 genesis.go,它將在創世狀態存儲具有相應硬幣餘額的帳戶映射。

package ledger

import (
     "io/ioutil"
     "encoding/json"
)

type Genesis struct {
     Balances map[Account]uint `json:"balances"`
}

func loadGenesis(path string) (Genesis, error) {
     genesisFileContent, err := ioutil.ReadFile(path)
     if err != nil {
          return Genesis{}, err
     }

     var loadedGenesis Genesis

     err = json.Unmarshal(genesisFileContent, &loadedGenesis)
     if err != nil {
          return Genesis{}, err
     }

return loadedGenesis, nil

核心業務邏輯將存儲在Store 結構中。創建一個名為的新文件 state.go. 狀態結構將包含所有賬戶餘額的詳細信息,誰將硬幣轉移給誰,以及轉移了多少硬幣。它必須知道如何從genesis 文件中讀取初始狀態。之後,創世狀態餘額按順序更新 重放所有交易 ledger.db 文件。最後,在這裡我們需要編寫一個將新交易添加到分類帳的邏輯。

package ledger

import (
     "fmt"
     "os"
     "path/filepath"
     "bufio"
     "encoding/json"
)

type State struct {
     Balances  map[Account]uint
     txMempool []Tx

     dbFile *os.File
}

func SyncState() (*State, error)  {
     cwd, err := os.Getwd()
     if err != nil {
          return nil, err
     }

     gen, err := loadGenesis(filepath.Join(cwd, "ledger", "genesis.json"))
     if err != nil {
          return nil, err
     }

     balances := make(map[Account]uint)
     for account, balance := range gen.Balances {
          balances[account] = balance
     }

     file, err := os.OpenFile(filepath.Join(cwd, "ledger", "ledger.db"), 
os.O_APPEND|os.O_RDWR, 0600)
     if err != nil {
          return nil, err
     }

     scanner := bufio.NewScanner(file)

     state := &State{balances, make([]Tx, 0), file}

     for scanner.Scan() {
          if err := scanner.Err(); err != nil {
               return nil, err
          }

          var transaction Tx
          json.Unmarshal(scanner.Bytes(), &transaction)

          if err := state.writeTransaction(transaction); err != nil {
               return nil, err
          }
     }

     return state, nil
}

func (s *State) writeTransaction(tx Tx) error {
     if s.Balances[tx.From] < tx.Value {
          return fmt.Errorf("insufficient balance")
     }

     s.Balances[tx.From] -= tx.Value
     s.Balances[tx.To] += tx.Value

     return nil
}

func (s *State) Close() {
     s.dbFile.Close()
}

func (s *State) WriteToLedger(tx Tx) error {
     if err := s.writeTransaction(tx); err != nil {
          return err
     }

     s.txMempool = append(s.txMempool, tx)

     mempool := make([]Tx, len(s.txMempool))
     copy(mempool, s.txMempool)

     for i := 0; i < len(mempool); i++ {
          txJson, err := json.Marshal(mempool[i])
          if err != nil {
               return err
          }

          if _, err = s.dbFile.Write(append(txJson, 'n')); err != nil {
               return err
          }
          s.txMempool = s.txMempool[1:]
     }

     return nil
}

開發命令行界面(CLI)

使用我們的新加密貨幣最簡單的方法是開發一個命令行界面(CLI)。在Go 中開發基於CLI 的程序的最簡單方法是使用 下一個第三方庫. 要使用這個庫,我們需要為我們的項目初始化Go 的內置依賴管理器,稱為Go 模塊。 Go 模塊命令將自動獲取您在Go 文件中引用的任何庫。

echo $GOPATH
cd $GOPATH/src/my-crypto-coin 
go mod init

現在讓我們創建一個新文件夾並命名它 cli. 但是等等,我們還沒有正式命名我們的加密貨幣!我們暫時稱它為My Crypto Coin。導航到 cli 文件夾並創建一個名為 mcc,是My Crypto Coin 的縮寫。導航到 mcc 文件夾。

創建一個名為的新文件 main.go. 這將是我們程序的主要入口。

package main

import (
     "github.com/spf13/cobra"
     "os"
     "fmt"
)

func main() {
     var mccCmd = &cobra.Command{
          Use:   "mcc",
          Short: "My Crypto Coin CLI",
          Run: func(cmd *cobra.Command, args []string) {
          },
     }

     mccCmd.AddCommand(versionCmd)
     mccCmd.AddCommand(balancesCmd())
     mccCmd.AddCommand(txCmd())

     err := mccCmd.Execute()
     if err != nil {
          fmt.Fprintln(os.Stderr, err)
          os.Exit(1)
     }
}

接下來,創建一個 version.go 文件並粘貼此內容。

package main

import (
     "fmt"
     "github.com/spf13/cobra"
)

const Major = "0"
const Minor = "1"
const Fix = "0"
const Verbal = "Genesis"

var versionCmd = &cobra.Command{
     Use:   "version",
     Short: "Describes version.",
     Run: func(cmd *cobra.Command, args []string) {
          fmt.Println(fmt.Sprintf("Version: %s.%s.%s-beta %s", Major, Minor, Fix, Verbal))
     },
}

之後,讓我們創建一種機制來從分類帳中讀取所有帳戶餘額。創建一個新的 balances.go 文件。

package main

import (
     "github.com/spf13/cobra"
     "my-crypto-coin/ledger"
     "fmt"
     "os"
)

func balancesCmd() *cobra.Command {
     var balancesCmd = &cobra.Command{
          Use:   "balances",
          Short: "Interact with balances (list...).",
          Run: func(cmd *cobra.Command, args []string) {
          },
     }

     balancesCmd.AddCommand(balancesListCmd)

     return balancesCmd
}

var balancesListCmd = &cobra.Command{
     Use:   "list",
     Short: "Lists all balances.",
     Run: func(cmd *cobra.Command, args []string) {
          state, err := ledger.SyncState()
          if err != nil {
               fmt.Fprintln(os.Stderr, err)
               os.Exit(1)
          }
          defer state.Close()

          fmt.Println("Accounts balances:")
          fmt.Println("__________________")
          fmt.Println("")
          for account, balance := range state.Balances {
               fmt.Println(fmt.Sprintf("%s: %d", account, balance))
          }
     },
}

最後,讓我們添加一個用於將交易寫入分類帳的命令。創建新的 tx.go 文件。

package main

import (
     "github.com/spf13/cobra"
     "my-crypto-coin/ledger"
     "fmt"
     "os"
)

func txCmd() *cobra.Command {
     var txsCmd = &cobra.Command{
          Use:   "tx",
          Short: "Interact with transactions (new...).",
          Run: func(cmd *cobra.Command, args []string) {
          },
     }

     txsCmd.AddCommand(newTxCmd())

     return txsCmd
}

func newTxCmd() *cobra.Command {
     var cmd = &cobra.Command{
          Use:   "new",
          Short: "Adds new TX to the ledger.",
          Run: func(cmd *cobra.Command, args []string) {
               from, _ := cmd.Flags().GetString("from")
               to, _ := cmd.Flags().GetString("to")
               value, _ := cmd.Flags().GetUint("value")

               tx := ledger.NewTx(ledger.NewAccount(from), ledger.NewAccount(to), 
value)

               state, err := ledger.SyncState()
               if err != nil {
                    fmt.Fprintln(os.Stderr, err)
                    os.Exit(1)
               }
               defer state.Close()
               err = state.WriteToLedger(tx)
               if err != nil {
                    fmt.Fprintln(os.Stderr, err)
                    os.Exit(1)
               }

               fmt.Println("TX successfully added to the ledger.")
          },
     }

     cmd.Flags().String("from", "", "From what account to send coins")
     cmd.MarkFlagRequired("from")

     cmd.Flags().String("to", "", "To what account to send coins")
     cmd.MarkFlagRequired("to")

     cmd.Flags().Uint("value", 0, "How many coins to send")
     cmd.MarkFlagRequired("value")

     return cmd
}


使用以下命令編譯程序:

go install $GOPATH/src/my-crypto-coin/cli/mcc/…


Go 將檢測丟失的庫並在編譯程序之前自動獲取它們。取決於你的 $GOPATH,生成的程序將保存在 $GOPATH/bin 文件夾。

要驗證安裝是否成功,請運行以下命令:

which mcc

您應該在終端中看到與此類似的路徑: /Users/yourname/go/bin/mcc. 讓我們看看所有可用的命令。跑:

mcc --help

要查看CLI 的當前版本,請運行:

mcc version

要查看當前用戶餘額,請運行以下命令:

mcc balances list

輸出應該是:

Accounts balances:
__________________

alice: 999895
bob: 95
carol: 10

現在讓我們使用CLI 進行第一個事務。輸入以下命令:

mcc tx new --from alice --to carol --value 10

如果你打開 ledger/ledger.db 文件,您應該能夠看到額外的一行:

{"from":"alice","to":"carol","value":10}

讓我們再次使用 mcc balances list 命令。輸出應該是:

Accounts balances:
__________________

alice: 999885
bob: 95
carol: 20

下一步是什麼?

目前,我們的用戶在賬本中用他們的名字表示。但是如果有兩個Bob 會發生什麼呢?我們需要添加一種使用通用散列算法唯一表示帳戶的方法。

下一個問題是任何人都可以使用我們的CLI 轉移其他人的代幣。我們需要一種方法來允許用戶使用公鑰密碼術只轉移他們擁有的硬幣。

如果我們的機器出現故障會發生什麼?沒有辦法重新創建我們的網絡,因為我們是網絡中唯一的節點。我們需要激勵人們加入我們的網絡並成為節點。一旦我們的網絡增長,我們將需要一種通用的方法來確定哪些交易是有效的,哪些不是,並驗證網絡的當前狀態。我們需要一個共識算法和機制。

概括

在本文中,您學習瞭如何使用Go 開發基本的加密貨幣,並且我們已經介紹了硬幣和代幣之間的主要區別。要了解更多信息,請前往 Chainlink 智能合約示例存儲庫 並開始試驗這個和其他示例項目。

通過訪問了解有關Chainlink 的更多信息 鏈環 或閱讀文檔 docs.chain.link. 要討論集成,請聯繫專家。

Source Link

最受歡迎

繼續閱讀

長期持有者持有的比特幣(BTC)供應量達到最高水平

根據Glassnode 的估計,比特幣的長期持有者(LTH)目前擁有1452 萬枚BTC,創歷史新高,只剩下25% 留給短期持...

抓住Web3 遊戲的先發優勢:成功策略

Web3和區塊鏈技術的出現徹底改變了遊戲行業,為開發者和企業家提供了前所未有的機遇。 Web3 遊戲的去中心化性質為創新遊戲貨幣化模式、玩家所有權和社區參與打...

現在讀

$COOKIE, the Cookie3 Mark...

Tallinn, Estonia, March 26th, 2024...

長期持有者持有的比特幣(BTC)供應量達到最高水平...

根據Glassnode 的估計,比特幣的長期持有者(LTH)目前擁有1452 萬枚BTC,創歷史新高,只剩下25% 留給短期持有者和投機者。 儘管BTC 的價格在過去一個月中保持相對平穩,範圍在約29,000 美元至31,000 美元之間,但人們還是開始瘋狂囤積。 ...

Caldera 宣布與Espresso Syste...

Caldera 開發人員可以利用Espresso Sequence...

抓住Web3 遊戲的先發優勢:成功策略

Web3和區塊鏈技術的出現徹底改變了遊戲行業,為開發者和企業家提供了前所未有的機遇。 Web3 遊戲的去中心化性質為創新遊戲貨幣化模式、玩家所有權和社區參與打開了大門。對於那些尋求利用Web3 遊戲巨大潛力的人來說,確保先發優勢至關重要。 了解Web3 遊戲生態系統在深入研究Web3 遊戲之前,有...

Taapsee Pannu 推出NFT 平台,介紹...

企業家貢獻者表達的意見是他們自己的。 您正在閱讀《企業家印度》,這是企業家媒體的國際特許經營刊物。 女演員Taapsee Pannu 最近推出了“taapseeclub.com”,這是她自己的非同質代...

比特幣(BTC) 地址休眠超過11 年,轉移310...

經過11 年多的閒置之後,一個包含3100 萬美元BTC 的休眠比特幣地址最近突然活躍起來。 2023年7月22日,地址 轉入 將其全部餘額轉移到新地址。 早期BTC 地址復活 比特幣自2009 年以來就已經存在,因此存在多年來不活躍的休眠地址,其中包含大量BTC。這種加密貨幣的一些早期採用者能夠...

加密貨幣死了嗎?當今加密貨幣的現狀

您之前可能聽說過加密貨幣正在消亡(或比特幣已消亡)。在這篇文章中,我們將研究加密貨幣的狀態,並嘗試回答這個問題:加密貨幣現在已經死了嗎? 在我們開始之前,我們想澄清一下,本文指的是最廣泛意義上的“加密貨幣行業”; 在裡面 網絡3 感覺。該定義包括加密資產市場; 但它還包括其他非財務用例。 隨著近來加...

Chancer 可能成為體育和社交博彩領域的下一個...

加密貨幣 隨著企業財報季節的繼續,本週股市表現好壞參半。在Ne...

以太坊(ETH) 創下兩個月來CEX 流入最高紀錄...

過去一周,以太坊(ETH)流入中心化交易所(CEX)的資金量創下了過去兩個月來的最高水平。這些重大的資產變動表明ETH 的價格可能會下跌。 CoinGecko 數據顯示,第二大加密貨幣的價格一直在小幅下跌,過去一周價值下跌了2.5%。截至撰寫本文時,以太幣易手價格為1,892.65 美元,過去24...

新的DeFi 法案有“不可行的義務”

加密貨幣創新委員會表示,新的反洗錢法案沒有為DeFi 中的非法金融...

幣安大幅削減成本,瑞波幣為美國銀行和加密貨幣風險投...

美國證券交易委員會(SEC)對加密貨幣公司的打擊似乎嚴重影響了幣安的業務。據報導,在過去幾週內,該加密貨幣交易所解雇了1,000 多名員工,並削減了一些福利。 幣安表示,“當前的市場環境和監管環境”導致利潤下降,這表明可能正在進行更多削減。一位發言人告訴Cointelegraph,該公司將考慮縮減“...

Automata 雙週更新:第48 期| 通過自動...

迎接新的季度意味著設定我們的意圖並為團隊規劃下一步的行動。幕後醞釀的一切——合作、產品功能和營銷發布——很難抑制我們的興奮。我們一開始就在1RPC(2 個備受期待的第2 層主網)上添加了對Linea 和Base 的支持。科技載體更新頁腳以顯示界面版本平滑的用戶體驗 USDC CCTP 支持 關於仲裁...