主頁 > 區塊鏈 > Flow區塊鏈門票NFT開發實戰【含原始碼】

Flow區塊鏈門票NFT開發實戰【含原始碼】

2021-08-15 08:16:44 區塊鏈

自從2017年提出ERC-721規范后,非同質化通證(NFT)已經從虛擬寵物交易的實驗性平臺發展到被主流行業大規模采用,在這個教程中,我們將門票作為一種NFT資產,利用FLow區塊鏈的Cadence智能合約來解決票務市場的主要痛點,例如防偽、中介手續費、二級市場混亂等問題,

在這里插入圖片描述

區塊鏈開發教程鏈接:以太坊 | 位元幣 | EOS | Tendermint | Hyperledger Fabric | Omni/USDT | Ripple | Tron

NBA Top Shot已經向其80萬用戶售賣了超過3億美元的NFT,索斯比則剛剛以1700萬美元的價格拍出一幅數字藝術品,當你購買一個NBA Top Shot藏品時,你并沒有獲得唯一的商業權力,你甚至不能獨享其權力,實際上那幅1700萬美元的藝術品,你可以免費觀賞,

不過讓我們探討下NFT帶來的價值:資產具有密碼學演算法可驗證的所有權以及合約賦予的售賣或轉讓能力,

很多型別的資產可以受益于密碼學可驗證的所有權:成績單、證書、知識產權等,想象一下用區塊鏈代替USPTO… 可以跳過律師直接提交你的申請,先到先服務,

是一個朋友的建議讓我看是考慮將門票作為一種NFT資產,這很有意義,票務市場最大的問題是什么?下面是一些:

  • 防偽
  • 大量的交易手續費,我們都知道當你看到50美元的門票卻需要花費72.50美元以便覆寫售票 中介的成本時的感覺
  • 不受監管的二級市場

如果我們使用智能合約來管理資產,這些問題就會消失,確定NFT的真實性是小事一樁,交易
手續費也可以通過采納區塊鏈得到大幅削減,

對我而言,最令人興奮的一點是票務發行人能夠設定二級市場條款,你可以讓你的資產不可轉讓,確保只能低于標價出售,甚至在任何二次銷售時幫助表演者削減成本,

在這個去中心化系統中,每個人都可以得到更公平透明的體驗,好了,讓我們開始這個系統的開發,

1、門票NFT的區塊鏈平臺選擇:以太坊 vs. Flow

我們需要做出的第一個決定,是選擇使用哪個區塊鏈平臺,

我們可以使用以太坊,但是交易手續費有點高,雖然在未來的ETH 2.0升級后手續費可能顯著下降,

Flow是一個開發者友好的新型區塊鏈生態,手續費微乎其微,聽起來是一個好的選擇,

實際上Dapper Lab的NBA Top Shot就是使用Flow智能合約,和我們下面要部署的合約沒有太多區別,

從較高的層面講,下面就是我們需要構造的一個基本但可用的票據集市,我們沒有實作完整的買/賣功能,不過這可能是下一個教程的主題,

  1. 在我們的Flow智能合約中定義票證的不可轉讓條款
  2. 創建虛擬賬號以便發行人和參與者能夠訪問NFT
  3. 使用交易來安全地展示常見功能,例如鑄造和票證轉讓
  4. 使用React.js實作一個簡單的前端web界面

2、Flow區塊鏈開發環境設定

我利用Flow檔案中的教程來熟悉其智能合約編程語言Cadence以及其標準的NFT模板,如果你打算遵循這一學習路徑,則需要安裝Flow CLI,

當然我們可以在Flow主網或測驗網部署合約,但是我們講利用FLow仿真器來進行快速本地開發,使用如下命令啟動仿真器:

flow emulator start

3、Flow區塊鏈門票NFT智能合約開發

我們的非同質化票證智能合約需要定義NFT的特點以及鑄造、存盤、轉讓等函式,其中某些功能需要公開可用,例如存入或獲取元資料,而另一些功能例如提取和鑄造,則需要一定的權限才可以執行,

我也希望確認我們的票證是不可轉讓的,因此我們需要設定必要的檢查條件以便禁止多次存入,下面看一下我們的Cadence智能合約,

// NonFungibleTicket.cdc
// contract to manage unique tradeable tickets (based on Flow NFT standard)
// see: https://docs.onflow.org/cadence/tutorial/04-non-fungible-tokens/

pub contract NonFungibleTicket {

    // set up a couple events for key deposits/withdrawals
    pub event Withdraw(id: UInt64, from: Address?)
    pub event Deposit(id: UInt64, to: Address?)

    // our NFT (Non-Fungible-Ticket) is simply defined by an id. metadata coming later
    pub resource NFT {
        pub let id: UInt64
        // we want to make our ticket non-transferrable, so let's keep track of how many times it has changed hands
        pub var numTransfers : UInt64

        init(initID: UInt64) {
            self.id = initID
            self.numTransfers = 0
        }
        // we will need a function to iterate the number of transfers each time
        pub fun transfer() {
            self.numTransfers = self.numTransfers + 1 as UInt64
        }
    }

    // receiver interface allows others to interact w certain functions via public access
    pub resource interface NFTReceiver {
        pub fun deposit(token: @NFT, metadata: {String : String})
        pub fun getIDs(): [UInt64]
        pub fun idExists(id: UInt64): Bool
        pub fun getMetadata(id: UInt64) : {String : String}
        // obviously, we don't allow public access to withdraw/minting functions
    }

    // defining a Collection resource for all our tickets
    pub resource Collection: NFTReceiver {
        pub var ownedNFTs: @{UInt64: NFT}
        pub var metadataObjs: {UInt64: { String : String }}

        init () {
            self.ownedNFTs <- {}
            self.metadataObjs = {}
        }

        // withdraw forced to be non-nil. function throws error if NFT with withdrawID doesn't exist
        pub fun withdraw(withdrawID: UInt64): @NFT {
            let token <- self.ownedNFTs.remove(key: withdrawID)!

            emit Withdraw(id: token.id, from: self.owner?.address)

            return <- token
        }

        // the deposit function is a bit more complex. first of all, this is where the metadata comes in:
        pub fun deposit(token: @NFT, metadata: {String : String}) {
            // our token can be transferred no more than once (from admin to attendee)
            if token.numTransfers > (1 as UInt64) {
                panic("Ticket is non-transferrable!")
            }
            self.metadataObjs[token.id] = metadata

            emit Deposit(id: token.id, to: self.owner?.address)
            // log the transfer (increases numTransfers by 1)
            token.transfer()
            self.ownedNFTs[token.id] <-! token
        }

        // rest of these are pretty straightforward
        pub fun idExists(id: UInt64): Bool {
            return self.ownedNFTs[id] != nil
        }


        pub fun getIDs(): [UInt64] {
            return self.ownedNFTs.keys
        }

        pub fun updateMetadata(id: UInt64, metadata: {String: String}) {
            self.metadataObjs[id] = metadata
        }

        pub fun getMetadata(id: UInt64): {String : String} {
            return self.metadataObjs[id]!
        }

        destroy() {
            destroy self.ownedNFTs
        }
    }

    // will need to create an empty collection for any account that wants our NFT
    pub fun createEmptyCollection(): @Collection {
        return <- create Collection()
    }

    // can explicitly share NFTMinter resource with another admin so that they can mint tickets
    pub resource NFTMinter {
        pub var idCount: UInt64

        init() {
            self.idCount = 1
        }

        pub fun mintNFT(): @NFT {
            var newNFT <- create NFT(initID: self.idCount)
            self.idCount = self.idCount + 1 as UInt64
            return <-newNFT
        }

    }

    // launching the contract does 3 things: 
    init() {
        // 1) save a fresh collection to the admin's storage
        self.account.save(<-self.createEmptyCollection(), to: /storage/NFTCollection)

        // 2) allow public access to NFTReceiver functions through this reference
        self.account.link<&{NFTReceiver}>(/public/NFTReceiver, target: /storage/NFTCollection)

        // 3) save NFTMinter resource to private storage
        self.account.save(<-create NFTMinter(), to: /storage/NFTMinter)
    }


}

關于Cadence,Flow官方檔案要比我介紹的更清楚,不過在更高的層面來說,Cadence使用Resources(資源)和Capabilities(能力)來定義誰(Who)可以訪問什么(What)功能,

例如,我們講NFTCollection和NFTMinter資源存入部署賬號的/storage/路徑,這意味著這些資源是私有的,但是我們在/public/路徑下發布一個指向NFTReceiver能力的鏈接,另外需要注意的是,我們的NFT只是簡單的利用其整數ID定義,并采用一個numTransfers計數器來記錄NFT的存入次數,

在這個示例中,如果某人試圖再次轉讓我們的票證,交易將失敗,將合約存入名為cadence/contracts/的目錄,

在我們部署合約之前,我們需要創建flow.json檔案來指定誰(Who)在哪里(Where)部署什么(What),在專案目錄中執行以下命令初始化這個檔案:

flow init

這會給我們一個啟動賬號以及相應的私鑰,稍后我們將查看flow.json檔案,但是首先我們需要為參與者創建一個賬號,運行下面的代碼來生成密鑰對:

flow keys generate

保存上述命令生成的密鑰對,然后運行:

flow accounts create ATTENDEE_PUB_KEY

將ATTENDEE_PUB_KEY替換為你剛剛生成的公鑰,

記錄下來0x開頭的地址,現在我們具備了flow.json需要的所有資料,

{
	"emulators": {
		"default": {
			"port": 3569,
			"serviceAccount": "emulator-account"
		}
	},
	"contracts": {
		"NonFungibleTicket": "./cadence/contracts/NonFungibleTicket.cdc"
	},
	"networks": {
		"emulator": "127.0.0.1:3569",
		"mainnet": "access.mainnet.nodes.onflow.org:9000",
		"testnet": "access.devnet.nodes.onflow.org:9000"
	},
	"accounts": {
		"emulator-account": {
			"address": "f8d6e0586b0a20c7",
			"keys": "e61fd9cbcf7d7d0918c5d02f79c9be08717ca82b5e7bd8c151e009eeb384bb78"
		},
		"attendee-account": {
			"address": "01cf0e2f2f715450",
			"keys": "ATTENDEE_PRIVATE_KEY"
		}
	},
	"deployments": {
		"emulator": {
			"emulator-account": ["NonFungibleTicket"]
		}
		
	}
}

注意:永遠不要共享你的私鑰,

你將看到我們在NonFungibleTicket合約中添加了一個指標(Pointer),我們的新的參與者賬號以及仿真器賬號(標識我們的票證發行人)的合約部署,現在我們可以用下面的命令部署合約:

flow project deploy

如果一切順利,你將會看到下面這樣的輸出:

Deploying 1 contracts for accounts: emulator-account
NonFungibleTicket -> 0xf8d6e0586b0a20c7
?  All contracts deployed successfully

4、鑄造Flow區塊鏈的門票NFT

現在是時候創建我們的第一個NFT了,下面我們將使用Cadence,但是我們將使用交易而不是定義一個合約,交易是我們使用智能合約中定義的函式的方法,交易執行將導致區塊鏈狀態的變化,

import NonFungibleTicket from 0xf8d6e0586b0a20c7

// This transaction allows the Minter account to mint an NFT
// and deposit it into its collection.

transaction {

    // The reference to the collection that will be receiving the NFT
    let receiverRef: &{NonFungibleTicket.NFTReceiver}

    // The reference to the Minter resource stored in account storage
    let minterRef: &NonFungibleTicket.NFTMinter

    prepare(acct: AuthAccount) {
        // Get the owner's collection capability and borrow a reference
        self.receiverRef = acct.getCapability<&{NonFungibleTicket.NFTReceiver}>(/public/NFTReceiver)
            .borrow()
            ?? panic("Could not borrow receiver reference")

        // Borrow a capability for the NFTMinter in storage
        self.minterRef = acct.borrow<&NonFungibleTicket.NFTMinter>(from: /storage/NFTMinter)
            ?? panic("Could not borrow minter reference")
    }

    execute {
        // Use the minter reference to mint an NFT, which deposits
        // the NFT into the collection that is sent as a parameter.
        let newNFT <- self.minterRef.mintNFT()

        let metadata : {String : String} = {
            "event": "FLOW LIVE in Concert!",
            "section": "200", 
            "row": "3", 
            "seat": "1",
            "uri": "https://flow-ticket-exchange.s3.amazonaws.com/ticket.png"
        }

        self.receiverRef.deposit(token: <-newNFT, metadata: metadata)

        log("Ticket minted and deposited into admin account")
    }
}

對我而言,這部分有趣的環節是NFT的元資料,我創建了一個演示用的具有若干屬性的票證,例如區域和排,以及一個指向票證影像的URI鏈接,

這引起了我的思考,我不知道是否輕量級NFT用戶理解其作業原理,

區塊鏈在跟蹤NFT的持有人以及其相關的元資料方面表現出色,然而,數字資產更常見的實作方式是采用外部存盤來保存這些資產的實際內容,

作為S3 bucket服務的用戶,沒有什么可以阻止我洗掉或更新這些檔案!

想象一下,你花費3萬美元購買了Steph Curry的3分球,然而Dapper Lab悄悄地將其替換為Alex Caruso的罰球!希望像IIPFS這樣的去中心化存盤方案能夠解決這一類問題,

我們的票務發行賬號部署合約,因此該賬號在其私有存盤中保存了NFTMinter資源,必須使用這個賬號來簽名如下交易:

flow transactions ./cadence/transactions/MintTicket.cdc send --signer emulator-account

如果我們嘗試用參與者賬號簽名,交易就會失敗,接下來讓我們用一個Cadence腳本來檢查我們的票務簽發賬號的余額,

import NonFungibleTicket from 0xf8d6e0586b0a20c7

pub fun main() : [UInt64] {
    let acct1 = getAccount(0xf8d6e0586b0a20c7)
    let capability1 = acct1.getCapability<&{NonFungibleTicket.NFTReceiver}>(/public/NFTReceiver)

    let receiverRef1 = capability1.borrow()
        ?? panic("Could not borrow the receiver reference")

    return receiverRef1.getIDs()
}

使用如下命令運行腳本:

flow scripts execute ./cadence/scripts/CheckTicketBalance.cdc

然后你將看到一個包含所持有NFT的ID的陣列:

Result: [1]

這表示發行賬號目前持有我們新鑄造的NFT!

5、使用Cadence腳本轉讓門票NFT

現在我們將把門票轉讓給一位熱切等待的樂迷,首先我們將在參與者的存盤中創建一個NFTCollection資源,

這讓我們有機會了解FLow架構的一個有用的方面,

在以太坊中,如果你將以太幣發送到一個無效的錢包地址,這些以太幣就沒了,然而在FLow中,在沒有明確的目標地址時資源不可能發送出去,或者整個交易回滾,我們不會因為手誤發送到無效地址而失去門票,

import NonFungibleTicket from 0xf8d6e0586b0a20c7

// This transaction configures a user's account
// to use the NFT contract by creating a new empty collection,
// storing it in their account storage, and publishing a capability
transaction {
  prepare(acct: AuthAccount) {

    // Create a new empty collection
    let collection <- NonFungibleTicket.createEmptyCollection()

    // store the empty NFT Collection in account storage
    acct.save<@NonFungibleTicket.Collection>(<-collection, to: /storage/NFTCollection)

    log("Collection created for account 2")

    // create a public capability for the Collection
    acct.link<&{NonFungibleTicket.NFTReceiver}>(/public/NFTReceiver, target: /storage/NFTCollection)

    log("Capability created")
  }
}

使用以上交易運行如下命令:

flow transactions send .\cadence\transactions\SetupEmptyCollection.cdc --signer attendee-account

現在我們的參與者已經準備接收票據了,我們將使用Cadence交易來完成這個操作,在這個交易中發行賬號取出其NFT然后存入參與者的藏品存盤,

別忘了每次存入時,合約都會增加存盤在NFT中的numTransfers引數的值,在這個交易之后,numTransfers = 1.
下面是合約的內容:

import NonFungibleTicket from 0xf8d6e0586b0a20c7

// This transaction transfers an NFT from one user's collection
// to another user's collection.
transaction {

    // The field that will hold the NFT as it is being
    // transferred to the other account
    let transferToken: @NonFungibleTicket.NFT
    let metadata: { String : String }

    prepare(acct: AuthAccount) {

        // Borrow a reference from the stored collection
        let collectionRef = acct.borrow<&NonFungibleTicket.Collection>(from: /storage/NFTCollection)
            ?? panic("Could not borrow a reference to the owner's collection")
        self.metadata = collectionRef.getMetadata(id: 1)
        // Call the withdraw function on the sender's Collection
        // to move the NFT out of the collection
        self.transferToken <- collectionRef.withdraw(withdrawID: 1)
    }

    execute {
        // Get the recipient's public account object
        let recipient = getAccount(0x01cf0e2f2f715450)

        // Get the Collection reference for the receiver
        // getting the public capability and borrowing a reference from it
        let receiverRef = recipient.getCapability<&{NonFungibleTicket.NFTReceiver}>(/public/NFTReceiver)
            .borrow()
            ?? panic("Could not borrow receiver reference")
        
        // Deposit the NFT in the receivers collection
        receiverRef.deposit(token: <-self.transferToken, metadata: self.metadata)

        log("NFT ID 1 transferred from account 2 to account 1")
    }
}

使用下面的命令轉讓門票:

flow transactions send ./cadence/transactions/TransferTicket.cdc --signer emulator-account

你可以分別用兩個賬號運行CheckTicketBalance腳本,驗證下getIDs()在使用發行賬號時回傳空陣列,而在使用參與者賬號時回傳[1]!接下來讓我們看看如果試圖將門票轉回發行賬號會發生什么情況,

? Transaction Error
execution error code 100: Execution failed:
error: panic: Ticket is non-transferrable!
  --> f8d6e0586b0a20c7.NonFungibleTicket:59:16
   |
59 |                 panic("Ticket is non-transferrable!")
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我們的智能合約正確地杜絕了這種情況的發生,我們的門票在二級市場不可以再次銷售!

6、門票NFT應用的React前端實作

我們不會深入介紹前端應用的細節,它主要是利用FLow JS庫訪問我們的Cadence合約,在這個簡單的示例程式中,我們讀取NFT的元資料,但是你可以用同樣的方法執行任何Cadence代碼,

import React, { useState, useEffect } from "react";
import * as fcl from "@onflow/fcl";
import { Address } from "@onflow/types";
import * as t from "@onflow/types"


const TokenData = () => {
  const [user, setUser] = useState({loggedIn: null})
  useEffect(() => fcl.currentUser().subscribe(setUser), [])
  const [nftInfo, setNftInfo] = useState(null)
  const fetchTokenData = async () => {
    const encoded = await fcl
      .send([
        fcl.script`
        import NonFungibleTicket from 0xf8d6e0586b0a20c7
        pub fun main() : {String : String} {
          let nftOwner = getAccount(0xf8d6e0586b0a20c7)  
          let capability = nftOwner.getCapability<&{NonFungibleTicket.NFTReceiver}>(/public/NFTReceiver)
      
          let receiverRef = capability.borrow()
              ?? panic("Could not borrow the receiver reference")
      
          return receiverRef.getMetadata(id: 1)
        }
      `
      ])
    
    const decoded = await fcl.decode(encoded)
    setNftInfo(decoded)
  };
  return (
    <div className="listing">
      <div className="center">
        <button className="btn-primary" onClick={fetchTokenData}>Fetch Token Data</button>        
      </div>
      {
        nftInfo &&
        <div>
          <div className="center">
            <p>Event: {nftInfo["event"]}</p>
            <p>Section: {nftInfo["section"]}</p>
            <p>Row: {nftInfo["row"]}</p>
            <p>Seat: {nftInfo["seat"]}</p>
          </div>
          <div className="center image">
            <img src={nftInfo["uri"]} alt="My NFT!" width="90%"/>
            <div>
              <button onClick={() => setNftInfo(null)} className="btn-secondary">Clear Token Info</button>
            </div>
          </div>
        </div>
        
      }
    </div>
  );
};

const OwnerData = (account) => {
  const [ownerInfo, setOwnerInfo] = useState(null)
  const fetchOwnerData = async () => {
    const encoded = await fcl
      .send([
        fcl.args(
          fcl.arg(account, t.Address)
        ),
        fcl.script`
        import NonFungibleTicket from 0xf8d6e0586b0a20c7
        pub fun main() : [UInt64] {
            let acct1 = getAccount(account) 
            let capability1 = acct1.getCapability<&{NonFungibleTicket.NFTReceiver}>(/public/NFTReceiver)
            let receiverRef1 = capability1.borrow()
                ?? panic("Could not borrow the receiver reference")
            return receiverRef1.getIDs()
        }
      `
      ])
    
    const decoded = await fcl.decode(encoded)
    setOwnerInfo(decoded)
  };
  return (
    <div>
      <p>Account: {account}</p>
      <p>Owned NFT's: {ownerInfo}</p>
    </div>
  );
};
export default TokenData;

使用如下命令啟動我們的前端應用:

npm run start

下面就是我們的簡單但強大的去中心化門票查看網頁:
在這里插入圖片描述

完整的代碼可以從這里下載,


原文鏈接:Flow區塊鏈門票NFT開發實戰及原始碼 —匯智網

轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/293796.html

標籤:區塊鏈

上一篇:記錄我在區塊鏈互聯網公司的實習生活Day23

下一篇:去中心化DeFi系統開發

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • JAVA使用 web3j 進行token轉賬

    最近新學習了下區塊鏈這方面的知識,所學不多,給大家分享下。 # 1. 關于web3j web3j是一個高度模塊化,反應性,型別安全的Java和Android庫,用于與智能合約配合并與以太坊網路上的客戶端(節點)集成。 # 2. 準備作業 jdk版本1.8 引入maven <dependency> < ......

    uj5u.com 2020-09-10 03:03:06 more
  • 以太坊智能合約開發框架Truffle

    前言 部署智能合約有多種方式,命令列的瀏覽器的渠道都有,但往往跟我們程式員的風格不太相符,因為我們習慣了在IDE里寫了代碼然后打包運行看效果。 雖然現在IDE中已經存在了Solidity插件,可以撰寫智能合約,但是部署智能合約卻要另走他路,沒辦法進行一個快捷的部署與測驗。 如果團隊管理的區塊節點多、 ......

    uj5u.com 2020-09-10 03:03:12 more
  • 谷歌二次驗證碼成為區塊鏈專用安全碼,你怎么看?

    前言 谷歌身份驗證器,前些年大家都比較陌生,但隨著國內互聯網安全的加強,它越來越多地出現在大家的視野中。 比較廣泛接觸的人群是國際3A游戲愛好者,游戲盜號現象嚴重+國外賬號安全應用廣泛,這類游戲一般都會要求用戶系結名為“兩步驗證”、“雙重驗證”等,平臺一般都推薦用谷歌身份驗證器。 后來區塊鏈業務風靡 ......

    uj5u.com 2020-09-10 03:03:17 more
  • 密碼學DAY1

    目錄 ##1.1 密碼學基本概念 密碼在我們的生活中有著重要的作用,那么密碼究竟來自何方,為何會產生呢? 密碼學是網路安全、資訊安全、區塊鏈等產品的基礎,常見的非對稱加密、對稱加密、散列函式等,都屬于密碼學范疇。 密碼學有數千年的歷史,從最開始的替換法到如今的非對稱加密演算法,經歷了古典密碼學,近代密 ......

    uj5u.com 2020-09-10 03:03:50 more
  • 密碼學DAY1_02

    目錄 ##1.1 ASCII編碼 ASCII(American Standard Code for Information Interchange,美國資訊交換標準代碼)是基于拉丁字母的一套電腦編碼系統,主要用于顯示現代英語和其他西歐語言。它是現今最通用的單位元組編碼系統,并等同于國際標準ISO/IE ......

    uj5u.com 2020-09-10 03:04:50 more
  • 密碼學DAY2

    ##1.1 加密模式 加密模式:https://docs.oracle.com/javase/8/docs/api/javax/crypto/Cipher.html ECB ECB : Electronic codebook, 電子密碼本. 需要加密的訊息按照塊密碼的塊大小被分為數個塊,并對每個塊進 ......

    uj5u.com 2020-09-10 03:05:42 more
  • NTP時鐘服務器的特點(京準電子)

    NTP時鐘服務器的特點(京準電子) NTP時鐘服務器的特點(京準電子) 京準電子官V——ahjzsz 首先對時間同步進行了背景介紹,然后討論了不同的時間同步網路技術,最后指出了建立全球或區域時間同步網存在的問題。 一、概 述 在通信領域,“同步”概念是指頻率的同步,即網路各個節點的時鐘頻率和相位同步 ......

    uj5u.com 2020-09-10 03:05:47 more
  • 標準化考場時鐘同步系統推進智能化校園建設

    標準化考場時鐘同步系統推進智能化校園建設 標準化考場時鐘同步系統推進智能化校園建設 安徽京準電子科技官微——ahjzsz 一、背景概述隨著教育事業的快速發展,學校建設如雨后春筍,隨之而來的學校教育、管理、安全方面的問題成了學校管理人員面臨的最大的挑戰,這些問題同時也是學生家長所擔心的。為了讓學生有更 ......

    uj5u.com 2020-09-10 03:05:51 more
  • 位元幣入門

    引言 位元幣基本結構 位元幣基礎知識 1)哈希演算法 2)非對稱加密技術 3)數字簽名 4)MerkleTree 5)哪有位元幣,有的是UTXO 6)位元幣挖礦與共識 7)區塊驗證(共識) 總結 引言 上一篇我們已經知道了什么是區塊鏈,此篇說一下區塊鏈的第一個應用——位元幣。其實先有位元幣,后有的區塊 ......

    uj5u.com 2020-09-10 03:06:15 more
  • 北斗對時服務器(北斗對時設備)電力系統應用

    北斗對時服務器(北斗對時設備)電力系統應用 北斗對時服務器(北斗對時設備)電力系統應用 京準電子科技官微(ahjzsz) 中國北斗衛星導航系統(英文名稱:BeiDou Navigation Satellite System,簡稱BDS),因為是目前世界范圍內唯一可以大面積提供免費定位服務的系統,所以 ......

    uj5u.com 2020-09-10 03:06:20 more
最新发布
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:46:47 more
  • Hyperledger Fabric 使用 CouchDB 和復雜智能合約開發

    在上個實驗中,我們已經實作了簡單智能合約實作及客戶端開發,但該實驗中智能合約只有基礎的增刪改查功能,且其中的資料管理功能與傳統 MySQL 比相差甚遠。本文將在前面實驗的基礎上,將 Hyperledger Fabric 的默認資料庫支持 LevelDB 改為 CouchDB 模式,以實作更復雜的資料... ......

    uj5u.com 2023-04-16 07:28:31 more
  • .NET Core 波場鏈離線簽名、廣播交易(發送 TRX和USDT)筆記

    Get Started NuGet You can run the following command to install the Tron.Wallet.Net in your project. PM> Install-Package Tron.Wallet.Net 配置 public reco ......

    uj5u.com 2023-04-14 08:08:00 more
  • DKP 黑客分析——不正確的代幣對比率計算

    概述: 2023 年 2 月 8 日,針對 DKP 協議的閃電貸攻擊導致該協議的用戶損失了 8 萬美元,因為 execute() 函式取決于 USDT-DKP 對中兩種代幣的余額比率。 智能合約黑客概述: 攻擊者的交易:0x0c850f,0x2d31 攻擊者地址:0xF38 利用合同:0xf34ad ......

    uj5u.com 2023-04-07 07:46:09 more
  • Defi開發簡介

    Defi開發簡介 介紹 Defi是去中心化金融的縮寫, 是一項旨在利用區塊鏈技術和智能合約創建更加開放,可訪問和透明的金融體系的運動. 這與傳統金融形成鮮明對比,傳統金融通常由少數大型銀行和金融機構控制 在Defi的世界里,用戶可以直接從他們的電腦或移動設備上訪問廣泛的金融服務,而不需要像銀行或者信 ......

    uj5u.com 2023-04-05 08:01:34 more
  • solidity簡單的ERC20代幣實作

    // SPDX-License-Identifier: GPL-3.0 pragma solidity >=0.7.0 <0.9.0; import "hardhat/console.sol"; //ERC20 同質化代幣,每個代幣的本質或性質都是相同 //ETH 是原生代幣,它不是ERC20代幣, ......

    uj5u.com 2023-03-21 07:56:29 more
  • solidity 參考型別修飾符memory、calldata與storage 常量修飾符C

    在solidity語言中 參考型別修飾符(參考型別為存盤空間不固定的數值型別) memory、calldata與storage,它們只能修飾參考型別變數,比如字串、陣列、位元組等... memory 適用于方法傳參、返參或在方法體內使用,使用完就會清除掉,釋放記憶體 calldata 僅適用于方法傳參 ......

    uj5u.com 2023-03-08 07:57:54 more
  • solidity注解標簽

    在solidity語言中 注釋符為// 注解符為/* 內容*/ 或者 是 ///內容 注解中含有這幾個標簽給予我們使用 @title 一個應該描述合約/介面的標題 contract, library, interface @author 作者的名字 contract, library, interf ......

    uj5u.com 2023-03-08 07:57:49 more
  • 評價指標:相似度、GAS消耗

    【代碼注釋自動生成方法綜述】 這些評測指標主要來自機器翻譯和文本總結等研究領域,可以評估候選文本(即基于代碼注釋自動方法而生成)和參考文本(即基于手工方式而生成)的相似度. BLEU指標^[^?88^^?^]^:其全稱是bilingual evaluation understudy.該指標是最早用于 ......

    uj5u.com 2023-02-23 07:27:39 more
  • 基于NOSTR協議的“公有制”版本的Twitter,去中心化社交軟體Damus

    最近,一個幽靈,Web3的幽靈,在網路游蕩,它叫Damus,這玩意詮釋了什么叫做病毒式營銷,滑稽的是,一個Web3產品卻在Web2的產品鏈上瘋狂傳銷,各方大佬紛紛為其背書,到底發生了什么?Damus的葫蘆里,賣的是什么藥? 注冊和簡單實用 很少有什么產品在用戶注冊環節會有什么噱頭,但Damus確實出 ......

    uj5u.com 2023-02-05 06:48:39 more