
如何创建Crypto Coin
原文链接:https://blog.chain.link/how-to-create-a-crypto-coin-zh/
原文标题:How To Create a Crypto Coin
原文作者:Andrej Rakic
货币是商品和服务的交换媒介。如今,货币采用纸币、硬币或中心化数字账本的形式,通常由政府发行,是一种被普遍接受的支付方式。过去,货币以各种金属的形式出现,如金银,甚至是彩色珠子和盐。Cryptocurrency是一种以密码学和区块链技术为基础的数字货币形式,主要用作转移价值的一种方式,而无需依赖单一的中心化平台,例如银行。
在本技术教程中,我们将探讨货币和通证之间的区别,你将学习如何开发自己的crypto coin。
我们开始吧!
货币和通证的区别
比特币是最流行的cryptocurrency,其主要目的是作为一种交换媒介。还有许多通证具有价值,但除了作为一种形式的交换媒介的作用之外,还有其他用途:例如,治理投票通证授予持有人某些治理特权。还有 NFT:代表独特事物所有权的不可替代通证。那么,所有这些类型的数字资产有什么区别呢?
从工程的角度来看,货币和通证之间的区别非常简单。货币是区块链的一部分,而通证以智能合约的形式运行在现有区块链上。
例如,BTC 是比特币区块链的币,ETH 是以太坊区块链的币。BTC 和 ETH 都是货币。再举几个例子,USDC、AAVE 和 WETH 都是通证,因为它们本质上是托管在以太坊区块链之上的智能合约。同样的原则也适用于 NFT:它们也是驻留在各种通用区块链上的通证。
要了解如何创建自己的通证,可查看这篇博客文章。要了解有关创建 NFT 的更多信息,可查看这个教程。继续阅读可了解有关创建自己的crypto coin的更多信息。
开始
这个项目是用 Go 编写的,但不需要以前有这种语言的经验。接下来,请查看位于My Crypto Coin文件夹下的Chainlink智能合约示例存储库(https://github.com/smartcontractkit/smart-contract-examples)中的完整工作示例。
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,然后粘贴下面的代码。我们将初始供应量为100万的crypto coin分配给Alice。
{
"genesis_time": "2022-04-12T00:00:00.000000000Z",
"chain_id": "our-blockchain",
"balances": {
"alice": 1000000
}
}
这是原始状态。交易会改变状态。如果我们的区块链节点出现故障,我们可以使用创世文件和交易历史来重新创建整个账本并将网络的其余部分同步到最新状态。
账户、交易和全局状态
导航到legder文件夹并创建一个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)
使用我们的新crypto coin最简单的方法是开发一个命令行界面 (CLI)。在Go中开发基于CLI 的程序的最简单方法是使用一个第三方库(Cobra。要使用这个库,我们需要为我们的项目初始化Go的内置依赖管理器,称为Go模块。Go模块命令将自动获取你在Go文件中引用的任何库。
echo $GOPATH
cd $GOPATH/src/my-crypto-coin
go mod init
现在让我们创建一个新文件夹并将其命名为cli。但是等等,我们还没有正式命名我们的crypto coin!我们暂时称它为 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会发生什么呢?我们需要添加一种使用通用散列算法唯一表示帐户的方法。
下一个问题是任何人都可以使用我们的命令行转移其他人的货币。我们需要一种方法来允许用户使用公钥密码技术仅转移他们自己拥有的货币。
如果我们的机器出现故障会发生什么?由于我们是网络中唯一的节点,因此无法重新创建我们的网络。我们需要激励人们加入我们的网络并成为节点。一旦我们的网络增长,我们将需要一种通用的方法来确定哪些交易是有效的,哪些不是,并验证网络的当前状态。我们需要一个共识算法和机制。
总结
在本文中,你学习了如何使用Go开发基本的crypto coin,并且我们已经介绍了货币和通证之间的主要区别。要了解更多信息,可前往Chainlink 智能合约示例存储库并开始试验这个和其他示例项目。
比推快讯
更多 >>- 以太坊 L2 TVL 回升至 330.8 亿美元,7 日涨幅 2.16%
- Coinbase 研究主管:所谓“史上 ETH 最大空头头寸”系严重夸大
- 说唱歌手 Drake 新歌中提及比特币
- 灰度:相信以太坊能够从美国加密货币友好政策转变中受益
- 下周宏观展望:特朗普关税“终审”倒计时
- 以太坊社区基金:致力于推动 ETH 达到 1 万美元,即将发布后续工作详情
- Sonic 空投第一阶段申领将于 7 月 15 日至 22 日期间随机开放
- 欧央行管委:欧元还未准备好挑战美元的全球储备货币地位
- 加密交易平台 NBX 完成 540 万挪威克朗融资,将用于增持比特币
- 1confirmation 创始人:全力支持 ETH,企业建立 ETH 财库或是好事
- 调查:78%的人表示特朗普的关税将使债务管理变得更加困难
- 柬埔寨与美国达成贸易协议,近期将发布对等关税的联合声明
- Vitalik Buterin:很多机构重视以太坊,以太坊将造福后代
- 众安在线完成 39 亿港元配售,旗下业务或将受益香港稳定币新政
- 疑似 Arthapala 的三个关联地址再次向币安充值 6789 枚 ETH
- 香港财库局长:稳定币储备资产只可放于优质、流动性高的资产
- 分析师:对新入场的公司而言,比特币财库策略的红利期或以结束
- 马斯克是否创建美国党投票已经有超 116 万人参与,65%赞成
- 过去 24 小时 CEX 净流入 5965.36 枚 BTC
- 香港财库局:正筹备发行第三批代币债券并推动贵金属等资产及金融工具代币化
- 徐明星回应账户误冻事件,承认合规系统存在误报问题
- 分析:DOGE 在 0.16 美元关键支撑位企稳
- 稳定币是什么话题登顶抖音热搜榜
- 以太坊上借贷协议的活跃贷款额达 226 亿美元,创历史新高
- 10xResearch:有猜测称休眠 14 年矿工巨鲸与比特币耶稣Roger Ver 有关
- 8 万枚“中本聪时代”比特币发生转移,总价值超 86 亿美元
- 瑞典上市公司 Fragbite Group 设立比特币资金业务部门并完成 48 万美元融资
- Bitdeer 上周比特币持仓新增 41.4 枚,总持仓量达 1527.5 枚
- RootData:Guild of Guardians 代币(GOG)24 小时涨幅达 42.99%
- 萨尔瓦多近 7 日共增持 8 枚 BTC,总持仓达 6228.18 枚
- Fragbite Group 达成 500 万瑞典克朗融资协议,拟支持购买比特币
- 特朗普:伊朗没有同意对其核项目进行检查,也没有同意放弃浓缩铀活动
- 赵长鹏:我进入加密领域的时机还是太晚了
- 黄山市黟县破获机票改签诈骗案,抓获加密货币洗钱团伙
- 特朗普:贸易信函已签署并将于周一发出
- 24 小时现货资金流入/流出榜:BTC 净流出 3.12 亿美元,ETH 净流出 1.5 亿美元
- RootData:G7 将于一周后解锁价值约 151 万美元的代币
- Project Hunt:公正实时的预测市场 Polymarket 为过去 7 天被 Top 人物取关最多的项目
- Bitcoin Treasury Capital:已获准在瑞典 Spotlight 股票市场上市,交易代码为 BTC
- Immutable:END 代币 TGE 已启动,申领已开放
- 某巨鲸地址昨晚或受恐慌情绪影响,将 1550 枚 BTC 转入 Binance
- Fragmetric 联创发文致歉,承认在 TGE 后的整体响应过于缓慢
- 数据:过去 24 小时全网爆仓 2.17 亿美元,多单爆仓 1.78 亿美元,空单爆仓 3920.49 万美元
- 10x Research:比特币 OG 钱包带来的潜在抛压,是比特币过去六个月难以实现显著涨幅的关键原因之一
- DoraHacks 发布黑客马拉松自动化智能体 BUIDL AI 3.0 版本
- 某个 2020 年囤积 WBTC 的巨鲸时隔 6 个月再次卖出 40 枚 WBTC
- 数据:超 30.4%的比特币在 5 年以上的时间里都未被动过
- 加密恐慌指数降至 67,市场贪婪情绪降温
- Binance Alpha 昨日交易量报 4.61 亿美元,BR、KOGE、BULLA 分列前三
- 数据:某巨鲸地址 8 小时前低位买入 1616 枚 ETH,价值约 403.8 万美元
比推专栏
更多 >>观点
比推热门文章
- 【比推一周web3新闻精选】路透社:Circle 申请美国银行牌照,拟托管 USDC 储备;美 SEC 已暂停灰度数字大盘基金转为 ETF 的计划,将进一步审查;特朗普“大而美”法案获通过,拜登、哈里斯接连发声批评
- 以太坊 L2 TVL 回升至 330.8 亿美元,7 日涨幅 2.16%
- Coinbase 研究主管:所谓“史上 ETH 最大空头头寸”系严重夸大
- 说唱歌手 Drake 新歌中提及比特币
- 灰度:相信以太坊能够从美国加密货币友好政策转变中受益
- 下周宏观展望:特朗普关税“终审”倒计时
- 以太坊社区基金:致力于推动 ETH 达到 1 万美元,即将发布后续工作详情
- Sonic 空投第一阶段申领将于 7 月 15 日至 22 日期间随机开放
- 欧央行管委:欧元还未准备好挑战美元的全球储备货币地位
- 加密交易平台 NBX 完成 540 万挪威克朗融资,将用于增持比特币