77 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			77 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|   | // Copyright 2016 The go-ethereum Authors | ||
|  | // This file is part of the go-ethereum library. | ||
|  | // | ||
|  | // The go-ethereum library is free software: you can redistribute it and/or modify | ||
|  | // it under the terms of the GNU Lesser General Public License as published by | ||
|  | // the Free Software Foundation, either version 3 of the License, or | ||
|  | // (at your option) any later version. | ||
|  | // | ||
|  | // The go-ethereum library is distributed in the hope that it will be useful, | ||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
|  | // GNU Lesser General Public License for more details. | ||
|  | // | ||
|  | // You should have received a copy of the GNU Lesser General Public License | ||
|  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | ||
|  | 
 | ||
|  | package bind | ||
|  | 
 | ||
|  | import ( | ||
|  | 	"fmt" | ||
|  | 	"time" | ||
|  | 
 | ||
|  | 	"github.com/ethereum/go-ethereum/common" | ||
|  | 	"github.com/ethereum/go-ethereum/core/types" | ||
|  | 	"github.com/ethereum/go-ethereum/logger" | ||
|  | 	"github.com/ethereum/go-ethereum/logger/glog" | ||
|  | 	"golang.org/x/net/context" | ||
|  | ) | ||
|  | 
 | ||
|  | // WaitMined waits for tx to be mined on the blockchain. | ||
|  | // It stops waiting when the context is canceled. | ||
|  | func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error) { | ||
|  | 	queryTicker := time.NewTicker(1 * time.Second) | ||
|  | 	defer queryTicker.Stop() | ||
|  | 	loghash := tx.Hash().Hex()[:8] | ||
|  | 	for { | ||
|  | 		receipt, err := b.TransactionReceipt(ctx, tx.Hash()) | ||
|  | 		if receipt != nil { | ||
|  | 			return receipt, nil | ||
|  | 		} | ||
|  | 		if err != nil { | ||
|  | 			glog.V(logger.Detail).Infof("tx %x error: %v", loghash, err) | ||
|  | 		} else { | ||
|  | 			glog.V(logger.Detail).Infof("tx %x not yet mined...", loghash) | ||
|  | 		} | ||
|  | 		// Wait for the next round. | ||
|  | 		select { | ||
|  | 		case <-ctx.Done(): | ||
|  | 			return nil, ctx.Err() | ||
|  | 		case <-queryTicker.C: | ||
|  | 		} | ||
|  | 	} | ||
|  | } | ||
|  | 
 | ||
|  | // WaitDeployed waits for a contract deployment transaction and returns the on-chain | ||
|  | // contract address when it is mined. It stops waiting when ctx is canceled. | ||
|  | func WaitDeployed(ctx context.Context, b DeployBackend, tx *types.Transaction) (common.Address, error) { | ||
|  | 	if tx.To() != nil { | ||
|  | 		return common.Address{}, fmt.Errorf("tx is not contract creation") | ||
|  | 	} | ||
|  | 	receipt, err := WaitMined(ctx, b, tx) | ||
|  | 	if err != nil { | ||
|  | 		return common.Address{}, err | ||
|  | 	} | ||
|  | 	if receipt.ContractAddress == (common.Address{}) { | ||
|  | 		return common.Address{}, fmt.Errorf("zero address") | ||
|  | 	} | ||
|  | 	// Check that code has indeed been deployed at the address. | ||
|  | 	// This matters on pre-Homestead chains: OOG in the constructor | ||
|  | 	// could leave an empty account behind. | ||
|  | 	code, err := b.CodeAt(ctx, receipt.ContractAddress, nil) | ||
|  | 	if err == nil && len(code) == 0 { | ||
|  | 		err = ErrNoCodeAfterDeploy | ||
|  | 	} | ||
|  | 	return receipt.ContractAddress, err | ||
|  | } |