-
Notifications
You must be signed in to change notification settings - Fork 20.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
accounts/abi/bind: parse ABI once #22583
Conversation
What is the full example? I'm wondering about the scope, really, because |
Oh you're right, that will clash with other definitions |
How about something like this? That makes it still load dynamically, but does so thread-safe and does not clutter the global scope with a lot of random things. The package foo
type parsedAbi struct {
mu sync.Mutex
sigs map[string]string
bin []byte
ab *abi.ABI
}
func (p *parsedAbi) getAbi(source string) (*abi.ABI, error) {
p.mu.Lock()
defer p.mu.Unlock()
if p.ab != nil {
return p.ab
}
if parsed, err := abi.JSON(strings.NewReader(source)); err != nil {
return nil, err
} else {
p.ab = parsed
}
}
var reverter = &parsedAbi{
sigs: map[string]string{"7da3c3ab": "revert()"},
bin: common.FromHex("0x6080604052348015600f57600080fd5b5060ab8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80637da3c3ab14602d575b600080fd5b60336035565b005b6040805162461bcd60e51b815260206004820152601160248201527072657665727420726561736f6e2031323360781b604482015290519081900360640190fdfea265627a7a72315820e8c3f899c32798b10b8d46594292b9e3d2271f011100fb17b6d3a6469f50c8c964736f6c63430005100032"),
}
// DeployReverter deploys a new Ethereum contract, binding an instance of Reverter to it.
func DeployReverter(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Reverter, error) {
rAbi, err := reverter.getAbi(ReverterABI)
if err != nil {
return common.Address{}, nil, nil, err
}
address, tx, contract, err := bind.DeployContract(auth, rAbi, rAbi.bin, backend)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &Reverter{ReverterCaller: ReverterCaller{contract: contract}, ReverterTransactor: ReverterTransactor{contract: contract}, ReverterFilterer: ReverterFilterer{contract: contract}}, nil
} |
@holiman I like it, however that would break the api as package foo
type ParsedAbi struct {
mu sync.Mutex
Sigs map[string]string
Bin []byte
ABI string
ab *abi.ABI
}
func (p *ParsedAbi) getAbi() (*abi.ABI, error) {
p.mu.Lock()
defer p.mu.Unlock()
if p.ab != nil {
return p.ab
}
if parsed, err := abi.JSON(strings.NewReader(p.ABI)); err != nil {
return nil, err
} else {
p.ab = parsed
}
}
// ReverterMetaData contains all meta data concerning the Reverter
var ReverterMetaData = &ParsedAbi{
Sigs: map[string]string{"7da3c3ab": "revert()"},
ABI: "[{\"constant\":false,\"inputs\":[],\"name\":\"revert\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]",
Bin: common.FromHex("0x6080604052348015600f57600080fd5b5060ab8061001e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c80637da3c3ab14602d575b600080fd5b60336035565b005b6040805162461bcd60e51b815260206004820152601160248201527072657665727420726561736f6e2031323360781b604482015290519081900360640190fdfea265627a7a72315820e8c3f899c32798b10b8d46594292b9e3d2271f011100fb17b6d3a6469f50c8c964736f6c63430005100032"),
}
// DeployReverter deploys a new Ethereum contract, binding an instance of Reverter to it.
func DeployReverter(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Reverter, error) {
rAbi, err := ReverterMetaData.getAbi()
if err != nil {
return common.Address{}, nil, nil, err
}
address, tx, contract, err := bind.DeployContract(auth, rAbi, rAbi.Bin, backend)
if err != nil {
return common.Address{}, nil, nil, err
}
return address, tx, &Reverter{ReverterCaller: ReverterCaller{contract: contract}, ReverterTransactor: ReverterTransactor{contract: contract}, ReverterFilterer: ReverterFilterer{contract: contract}}, nil
} |
Yeah, that looks good to me. If you don't want to break the api, maybe keep them, but remove then at some point? Something like:
|
8319056
to
aa29458
Compare
aa29458
to
8d38133
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
This moves the initialization of the parsedABI object from the Deploy()
function into a var that gets executed on startup. This means deploying
the same contract multiple times becomes faster, as the ABI doesn't have
to be parsed every time. It does increase the memory usage by requiring
everyone to hold the ABI object in memory even if the contract is not
going to be deployed.
closes #22269
example: (updated)