<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      區塊鏈應用與以太坊的交互

      我們要談的交互

      首先要明確一點,以太坊是一個去中心化的平臺,他不可能為了某個項目而新增交互接口。
      我這里說的交互是指應用是鏈上合約的交互,更明確的說,是chainlink,arbitrum,cosmos這些鏈下應用與鏈上合約的交互。
      所以這里我不是想說以下交互方式:

      • 通過錢包交互:將應用打包成一個網頁,連接類似與小狐貍 這樣的錢包,與鏈發生交互。
      • 手動構造交易:構建交易tx并使用私鑰對交易進行簽名,然后直接發送到鏈給定的接口上。

      對于一些簡單的調用,通過上面兩種方式是可行的,例如我們只是做一些nft的構造,通過錢包是最合適的。但是對于向arbitrum這類
      鏈上的應用,如果要做一個交互式單步證明,在這個過程中我需要監控鏈上合約拋出的event,分析event并構造出相應結果。
      這個時候錢包就很難插手,而如果主動構造交易并簽名,那么過程太繁瑣。實際上以太坊上已經提供了相關的工具鏈。

      我們要談的交互方式就是,通過以太坊支持的工具鏈實現與以太坊的交互

      工具鏈

      工具鏈

      簡單而言是使用以太坊工具將sol的合約代碼轉換成go的類文件,并對調用細節進行封裝。
      而在應用層(arbitrum,chainlink這一層)可以直接將對應參數傳過去就可以.

      以arbitrum為例:

      生成go代碼

      生成工具在: https://github.com/OffchainLabs/nitro/blob/master/solgen/gen.go
      由于arbitrum用到鏈makefile,所我們沒法通過運行這個文件(go run gen.go)的方式,去生成合約文件。
      不過實際上這是一個路徑的問題,在代碼的第71行:

          filePaths, err := filepath.Glob(filepath.Join(parent, "contracts", "build", "contracts", "src", "*", "*.sol", "*.json"))
      	if err != nil {
      		log.Fatal(err)
      	}
      
      	filePathsSafeSmartAccount, err := filepath.Glob(filepath.Join(parent, "safe-smart-account", "build", "artifacts", "contracts", "*", "*.sol", "*.json"))
      	if err != nil {
      		log.Fatal(err)
      	}
      	filePathsSafeSmartAccountOuter, err := filepath.Glob(filepath.Join(parent, "safe-smart-account", "build", "artifacts", "contracts", "*.sol", "*.json"))
      	if err != nil {
      		log.Fatal(err)
      	}
      

      這里實際上就指定了合約代碼的路徑,當然如果只是初次下載合約文件應該是看不到build目錄的,需要在合約所在項目構建一下,才能生成這個build文件

      構造方法:

      yarn --cwd contracts build
      yarn --cwd contracts build:forge:yul
      # 其實就是hardhat compile的產物
      

      然后就會在solgen這個目錄下生成對應的go文件
      solgen

      我們具體看一下這個生成的代碼怎么用

      使用生成的代碼

      首先可以看到在生成的代碼中,每一個合約都有一個對應的類
      eg:

      // ChallengeLibTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
      type ChallengeLibTransactorRaw struct {
      	Contract *ChallengeLibTransactor // Generic write-only contract binding to access the raw methods on
      }
      

      合約中的方法則對應到類的方法

      eg:

      // Solidity: function oneStepProveExecution(uint64 challengeIndex, (uint256,uint256,bytes32[],uint256) selection, bytes proof) returns()
      func (_ChallengeManager *ChallengeManagerTransactor) OneStepProveExecution(opts *bind.TransactOpts, challengeIndex uint64, selection ChallengeLibSegmentSelection, proof []byte) (*types.Transaction, error) {
      	return _ChallengeManager.contract.Transact(opts, "oneStepProveExecution", challengeIndex, selection, proof)
      }
      

      其中關鍵在與這里的opts,如果我們繼續進到這個Transact方法里面會發現,鏈上的信息都是由這里的opts獲取的,用戶簽名接口,用戶信息等

      那么對于一個合約調用就分為兩部分,一是調用參數,也就是這里的opts和合約參數,一是對接一臺的的client

      參數

      進入到這里的opts,這是以太坊里面的數據結構

      // valid Ethereum transaction.
      type TransactOpts struct {
      	From   common.Address // Ethereum account to send the transaction from
      	Nonce  *big.Int       // Nonce to use for the transaction execution (nil = use pending state)
      	Signer SignerFn       // Method to use for signing the transaction (mandatory)
      
      	Value     *big.Int // Funds to transfer along the transaction (nil = 0 = no funds)
      	GasPrice  *big.Int // Gas price to use for the transaction execution (nil = gas price oracle)
      	GasFeeCap *big.Int // Gas fee cap to use for the 1559 transaction execution (nil = gas price oracle)
      	GasTipCap *big.Int // Gas priority fee cap to use for the 1559 transaction execution (nil = gas price oracle)
      	GasLimit  uint64   // Gas limit to set for the transaction execution (0 = estimate)
      	GasMargin uint64   // Arbitrum: adjusts gas estimate by this many basis points (0 = no adjustment)
      
      	Context context.Context // Network context to support cancellation and timeouts (nil = no timeout)
      
      	NoSend bool // Do all transact steps but do not send the transaction
      }
      

      我們可以看到,這里包含用戶信息的簽名數據

      對于鏈下的開發者,我們需要構造這個結構,來調用方法

      client

      我們有鏈合約的調用參數,那么就需要有一個client來為我們發送交易,(雖然構造交易的時候也用到鏈client,但這都是已經被工具封裝好的,開發者沒必要細究它是怎么構建的)

      實際上client是在我們構建合約對象時構建的

      // NewChallengeManager creates a new instance of ChallengeManager, bound to a specific deployed contract.
      func NewChallengeManager(address common.Address, backend bind.ContractBackend) (*ChallengeManager, error) {
      	contract, err := bindChallengeManager(address, backend, backend, backend)
      	if err != nil {
      		return nil, err
      	}
      	return &ChallengeManager{ChallengeManagerCaller: ChallengeManagerCaller{contract: contract}, ChallengeManagerTransactor: ChallengeManagerTransactor{contract: contract}, ChallengeManagerFilterer: ChallengeManagerFilterer{contract: contract}}, nil
      }
      

      在構建ChallengeManger這個合約對象時,我們需要給他一個backend,這里的backend就是鏈的client,地址也就是鏈上的合約地址

      可以看到backend也是bind這個包里面的,實際上它也是以太坊源碼里面的包

      type ContractBackend interface {
      	ContractCaller
      	ContractTransactor
      	ContractFilterer
      }
      
      type ContractCaller interface {
      	// CodeAt returns the code of the given account. This is needed to differentiate
      	// between contract internal errors and the local chain being out of sync.
      	CodeAt(ctx context.Context, contract common.Address, blockNumber *big.Int) ([]byte, error)
      
      	// CallContract executes an Ethereum contract call with the specified data as the
      	// input.
      	CallContract(ctx context.Context, call ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
      }
      type ContractTransactor interface {
      	ethereum.GasEstimator
      	ethereum.GasPricer
      	ethereum.GasPricer1559
      	ethereum.TransactionSender
      
      	// HeaderByNumber returns a block header from the current canonical chain. If
      	// number is nil, the latest known header is returned.
      	HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error)
      
      	// PendingCodeAt returns the code of the given account in the pending state.
      	PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
      
      	// PendingNonceAt retrieves the current pending nonce associated with an account.
      	PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
      }
      
      type ContractFilterer interface {
      	ethereum.LogFilterer
      }
      

      這個client看起來構造很麻煩,實際上也是有跡可循的,這里面都是以太坊里的數據結構,所以理論上以太坊里面已經有對象實現了這些接口

      type Client struct {
      	c rpc.ClientInterface
      }
      type ClientInterface interface {
      	CallContext(ctx_in context.Context, result interface{}, method string, args ...interface{}) error
      	EthSubscribe(ctx context.Context, channel interface{}, args ...interface{}) (*ClientSubscription, error)
      	BatchCallContext(ctx context.Context, b []BatchElem) error
      	Close()
      }
      
      // Client represents a connection to an RPC server.
      type Client struct {
      	idgen    func() ID // for subscriptions
      	isHTTP   bool      // connection type: http, ws or ipc
      	services *serviceRegistry
      
      	idCounter atomic.Uint32
      
      	// This function, if non-nil, is called when the connection is lost.
      	reconnectFunc reconnectFunc
      
      	// config fields
      	batchItemLimit       int
      	batchResponseMaxSize int
      
      	// writeConn is used for writing to the connection on the caller's goroutine. It should
      	// only be accessed outside of dispatch, with the write lock held. The write lock is
      	// taken by sending on reqInit and released by sending on reqSent.
      	writeConn jsonWriter
      
      	// for dispatch
      	close       chan struct{}
      	closing     chan struct{}    // closed when client is quitting
      	didClose    chan struct{}    // closed when client quits
      	reconnected chan ServerCodec // where write/reconnect sends the new connection
      	readOp      chan readOp      // read messages
      	readErr     chan error       // errors from read
      	reqInit     chan *requestOp  // register response IDs, takes write lock
      	reqSent     chan error       // signals write completion, releases write lock
      	reqTimeout  chan *requestOp  // removes response IDs when call timeout expires
      }
      
      posted @ 2024-09-11 17:21  bighu  閱讀(193)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲成av人片乱码色午夜| 国模肉肉视频一区二区三区| 亚洲一区二区三区自拍麻豆| 久久精品亚洲精品国产色婷| 亚洲永久一区二区三区在线 | 中文字幕日韩有码国产| 天堂俺去俺来也www色官网| 国产精品日韩av在线播放| 国内免费视频成人精品| 国产成人精品午夜二三区 | 日韩av一区二区三区不卡| 亚洲国产成人精品女久久| 日本黄页网站免费观看| 亚洲国产精品久久久久秋霞| 北岛玲亚洲一区二区三区| 国内精品久久久久影院日本| 国产精品三级黄色小视频| √天堂中文www官网在线| 板桥市| 国产一区二区三区尤物视频| A级日本乱理伦片免费入口| 无码AV无码免费一区二区 | 精品国产中文字幕在线看| 亚洲精品一品区二品区三品区 | 亚洲色大成网站WWW永久麻豆| 在线日韩日本国产亚洲| 日韩精品亚洲专区在线观看| 六十路熟妇乱子伦| 国产一区视频一区欧美| 国产精品一区高清在线观看| 婷婷四虎东京热无码群交双飞视频| 国产精品1区2区3区在线观看| 欧美精品一区二区三区中文字幕| 中文字幕无码久久精品| 狠狠亚洲色一日本高清色| 九九热精品免费在线视频| 欧美无人区码suv| 国产欧美日韩精品丝袜高跟鞋| 偷拍精品一区二区三区 | 18分钟处破好疼哭视频在线观看 | 亚洲色大成网站www永久一区|