Get method/event signature from ABI (#17)

This commit is contained in:
Elizabeth 2018-09-12 08:59:43 -05:00 committed by GitHub
parent 4b6ef1e58b
commit faefd620b1
7 changed files with 106 additions and 149 deletions

View File

@ -1,31 +0,0 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shared
import (
"github.com/ethereum/go-ethereum/common"
"math/big"
)
type Bid struct {
Bid *big.Int
Lot *big.Int
Guy common.Address
Tic *big.Int
End *big.Int
Lad [32]byte
Gal common.Address
Tab *big.Int
}

View File

@ -1,45 +0,0 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shared
import (
"github.com/vulcanize/vulcanizedb/pkg/core"
)
type IBidFetcher interface {
FetchBid(contractAbi, contractAddress string, blockNumber int64, methodArgs interface{}) (Bid, error)
}
type BidFetcher struct {
blockChain core.BlockChain
}
func NewBidFetcher(blockchain core.BlockChain) IBidFetcher {
return BidFetcher{
blockChain: blockchain,
}
}
func (fetcher BidFetcher) FetchBid(contractAbi, contractAddress string, blockNumber int64, methodArgs interface{}) (Bid, error) {
method := "bids"
result := Bid{}
err := fetcher.blockChain.FetchContractData(contractAbi, contractAddress, method, methodArgs, &result, blockNumber)
if err != nil {
return result, err
}
return result, nil
}

View File

@ -1,57 +0,0 @@
// Copyright 2018 Vulcanize
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package shared_test
import (
"math/big"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/vulcanize/vulcanizedb/pkg/fakes"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
)
var _ = Describe("Dent Bid BidFetcher", func() {
var blockChain *fakes.MockBlockChain
var fetcher shared.IBidFetcher
var blockNumber = int64(123)
var address = "0xfakeAddress"
var contractAbi = "contractAbi"
BeforeEach(func() {
blockChain = fakes.NewMockBlockChain()
fetcher = shared.NewBidFetcher(blockChain)
})
It("fetches a bid record for the given id", func() {
method := "bids"
bidId := big.NewInt(1)
result := &shared.Bid{}
_, err := fetcher.FetchBid(contractAbi, address, blockNumber, bidId)
Expect(err).NotTo(HaveOccurred())
blockChain.AssertFetchContractDataCalledWith(contractAbi, address, method, bidId, result, blockNumber)
})
It("returns an error if fetching the bid fails", func() {
blockChain.SetFetchContractDataErr(fakes.FakeError)
fetcher := shared.NewBidFetcher(blockChain)
_, err := fetcher.FetchBid(contractAbi, address, blockNumber, nil)
Expect(err).To(HaveOccurred())
Expect(err).To(MatchError(fakes.FakeError))
})
})

View File

@ -17,17 +17,6 @@ package shared
var (
DataItemLength = 32
biteMethod = "Bite(bytes32,bytes32,uint256,uint256,uint256,uint256,uint256)"
dentMethod = "dent(uint256,uint256,uint256)"
flipKickMethod = "Kick(uint256,uint256,uint256,address,uint48,bytes32,uint256)"
frobMethod = "Frob(bytes32,bytes32,uint256,uint256,int256,int256,uint256)"
logValueMethod = "LogValue(bytes32)"
pitFileDebtCeilingMethod = "file(bytes32,uint256)"
pitFileIlkMethod = "file(bytes32,bytes32,uint256)"
pitFileStabilityFeeMethod = "file(bytes32,address)"
tendMethod = "tend(uint256,uint256,uint256)"
vatInitMethod = "init(bytes32)"
CatABI = "[{\"constant\":true,\"inputs\":[],\"name\":\"vat\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"vow\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"flips\",\"outputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"lad\",\"type\":\"bytes32\"},{\"name\":\"ink\",\"type\":\"uint256\"},{\"name\":\"tab\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"nflip\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"live\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"address\"}],\"name\":\"wards\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"ilks\",\"outputs\":[{\"name\":\"flip\",\"type\":\"address\"},{\"name\":\"chop\",\"type\":\"uint256\"},{\"name\":\"lump\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"pit\",\"outputs\":[{\"name\":\"\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"name\":\"vat_\",\"type\":\"address\"},{\"name\":\"pit_\",\"type\":\"address\"},{\"name\":\"vow_\",\"type\":\"address\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"ilk\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"lad\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"ink\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"art\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"tab\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"flip\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"iArt\",\"type\":\"uint256\"}],\"name\":\"Bite\",\"type\":\"event\"},{\"anonymous\":true,\"inputs\":[{\"indexed\":true,\"name\":\"sig\",\"type\":\"bytes4\"},{\"indexed\":true,\"name\":\"guy\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"foo\",\"type\":\"bytes32\"},{\"indexed\":true,\"name\":\"bar\",\"type\":\"bytes32\"},{\"indexed\":false,\"name\":\"wad\",\"type\":\"uint256\"},{\"indexed\":false,\"name\":\"fax\",\"type\":\"bytes\"}],\"name\":\"LogNote\",\"type\":\"event\"},{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"rely\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"guy\",\"type\":\"address\"}],\"name\":\"deny\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"what\",\"type\":\"bytes32\"},{\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"file\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"what\",\"type\":\"bytes32\"},{\"name\":\"flip\",\"type\":\"address\"}],\"name\":\"file\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"ilk\",\"type\":\"bytes32\"},{\"name\":\"lad\",\"type\":\"bytes32\"}],\"name\":\"bite\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"n\",\"type\":\"uint256\"},{\"name\":\"wad\",\"type\":\"uint256\"}],\"name\":\"flip\",\"outputs\":[{\"name\":\"id\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
FlipperABI = `[{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"bids","outputs":[{"name":"bid","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"guy","type":"address"},{"name":"tic","type":"uint48"},{"name":"end","type":"uint48"},{"name":"urn","type":"bytes32"},{"name":"gal","type":"address"},{"name":"tab","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x4423c5f1"},{"constant":true,"inputs":[],"name":"ttl","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x4e8b1dd5"},{"constant":true,"inputs":[],"name":"gem","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7bd2bea7"},{"constant":true,"inputs":[],"name":"beg","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x7d780d82"},{"constant":true,"inputs":[],"name":"tau","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xcfc4af55"},{"constant":true,"inputs":[],"name":"kicks","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xcfdd3302"},{"constant":true,"inputs":[],"name":"dai","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function","signature":"0xf4b9fa75"},{"inputs":[{"name":"dai_","type":"address"},{"name":"gem_","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor","signature":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"id","type":"uint256"},{"indexed":false,"name":"lot","type":"uint256"},{"indexed":false,"name":"bid","type":"uint256"},{"indexed":false,"name":"gal","type":"address"},{"indexed":false,"name":"end","type":"uint48"},{"indexed":true,"name":"urn","type":"bytes32"},{"indexed":false,"name":"tab","type":"uint256"}],"name":"Kick","type":"event","signature":"0xbac86238bdba81d21995024470425ecb370078fa62b7271b90cf28cbd1e3e87e"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event","signature":"0x644843f351d3fba4abcd60109eaff9f54bac8fb8ccf0bab941009c21df21cf31"},{"constant":true,"inputs":[],"name":"era","outputs":[{"name":"","type":"uint48"}],"payable":false,"stateMutability":"view","type":"function","signature":"0x143e55e0"},{"constant":false,"inputs":[{"name":"urn","type":"bytes32"},{"name":"gal","type":"address"},{"name":"tab","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"kick","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xeae19d9e"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"tick","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xfc7b6aee"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"tend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x4b43ed12"},{"constant":false,"inputs":[{"name":"id","type":"uint256"},{"name":"lot","type":"uint256"},{"name":"bid","type":"uint256"}],"name":"dent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0x5ff3a382"},{"constant":false,"inputs":[{"name":"id","type":"uint256"}],"name":"deal","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function","signature":"0xc959c42b"}]`
MedianizerABI = `[{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"","type":"bytes32"}],"name":"poke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"poke","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"compute","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"wat","type":"address"}],"name":"unset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"indexes","outputs":[{"name":"","type":"bytes12"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"next","outputs":[{"name":"","type":"bytes12"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"read","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"peek","outputs":[{"name":"","type":"bytes32"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes12"}],"name":"values","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"min_","type":"uint96"}],"name":"setMin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"void","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"},{"name":"wat","type":"address"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"pos","type":"bytes12"}],"name":"unset","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"next_","type":"bytes12"}],"name":"setNext","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"min","outputs":[{"name":"","type":"uint96"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[{"indexed":false,"name":"val","type":"bytes32"}],"name":"LogValue","type":"event"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"}]]`
@ -43,6 +32,18 @@ var (
RepContractAddress = "0xF5f94b7F9De14D43112e713835BCef2d55b76c1C"
VatContractAddress = "0x239E6f0AB02713f1F8AA90ebeDeD9FC66Dc96CD6"
biteMethod = GetSolidityMethodSignature(CatABI, "Bite")
dentMethod = GetSolidityMethodSignature(FlipperABI, "dent")
flipKickMethod = GetSolidityMethodSignature(FlipperABI, "Kick")
frobMethod = GetSolidityMethodSignature(PitABI, "Frob")
//TODO: get these pit file method signatures directly from the ABI
pitFileDebtCeilingMethod = "file(bytes32,uint256)"
pitFileIlkMethod = "file(bytes32,bytes32,uint256)"
pitFileStabilityFeeMethod = GetSolidityMethodSignature(PitABI, "file")
tendMethod = GetSolidityMethodSignature(FlipperABI, "tend")
logValueMethod = GetSolidityMethodSignature(MedianizerABI, "LogValue")
vatInitMethod = GetSolidityMethodSignature(VatABI, "init")
BiteSignature = GetEventSignature(biteMethod)
DentFunctionSignature = GetLogNoteSignature(dentMethod)
FlipKickSignature = GetEventSignature(flipKickMethod)

View File

@ -14,7 +14,13 @@
package shared
import "github.com/ethereum/go-ethereum/crypto"
import (
"github.com/ethereum/go-ethereum/crypto"
"github.com/vulcanize/vulcanizedb/pkg/geth"
"github.com/ethereum/go-ethereum/accounts/abi"
"fmt"
"strings"
)
func GetEventSignature(solidityMethodSignature string) string {
eventSignature := []byte(solidityMethodSignature)
@ -26,3 +32,25 @@ func GetLogNoteSignature(solidityMethodSignature string) string {
rawSignature := GetEventSignature(solidityMethodSignature)
return rawSignature[:10] + "00000000000000000000000000000000000000000000000000000000"
}
func GetSolidityMethodSignature(abi, name string) string {
parsedAbi, _ := geth.ParseAbi(abi)
if method, ok := parsedAbi.Methods[name]; ok {
return method.Sig()
} else if event, ok := parsedAbi.Events[name]; ok {
return getEventSignature(event)
}
return ""
}
func getEventSignature(event abi.Event) string {
types := make([]string, len(event.Inputs))
for i, input := range event.Inputs {
types[i] = input.Type.String()
i++
}
return fmt.Sprintf("%v(%v)", event.Name, strings.Join(types, ","))
}

View File

@ -81,4 +81,68 @@ var _ = Describe("Event signature generator", func() {
Expect(expected).To(Equal(actual))
})
})
Describe("getting the solidity method/event signature from the abi", func() {
Describe("it handles methods", func() {
It("gets the flip dent method signature", func() {
expected := "dent(uint256,uint256,uint256)"
actual := shared.GetSolidityMethodSignature(shared.FlipperABI, "dent")
Expect(expected).To(Equal(actual))
})
It("gets the flip tend method signature", func() {
expected := "tend(uint256,uint256,uint256)"
actual := shared.GetSolidityMethodSignature(shared.FlipperABI, "tend")
Expect(expected).To(Equal(actual))
})
It("gets the pit file deb ceiling method signature", func() {
expected := "file(bytes32,address)"
actual := shared.GetSolidityMethodSignature(shared.PitABI, "file")
Expect(expected).To(Equal(actual))
})
It("gets the vat init method signature", func() {
expected := "init(bytes32)"
actual := shared.GetSolidityMethodSignature(shared.VatABI, "init")
Expect(expected).To(Equal(actual))
})
})
Describe("it handles events", func() {
It("gets the Bite event signature", func() {
expected := "Bite(bytes32,bytes32,uint256,uint256,uint256,uint256,uint256)"
actual := shared.GetSolidityMethodSignature(shared.CatABI, "Bite")
Expect(expected).To(Equal(actual))
})
It("gets the flip Kick event signature", func() {
expected := "Kick(uint256,uint256,uint256,address,uint48,bytes32,uint256)"
actual := shared.GetSolidityMethodSignature(shared.FlipperABI, "Kick")
Expect(expected).To(Equal(actual))
})
It("gets the pit frob event signature", func() {
expected := "Frob(bytes32,bytes32,uint256,uint256,int256,int256,uint256)"
actual := shared.GetSolidityMethodSignature(shared.PitABI, "Frob")
Expect(expected).To(Equal(actual))
})
It("gets the log value method signature", func() {
expected := "LogValue(bytes32)"
actual := shared.GetSolidityMethodSignature(shared.MedianizerABI, "LogValue")
Expect(expected).To(Equal(actual))
})
})
})
})

View File

@ -22,16 +22,13 @@ import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/vulcanize/vulcanizedb/pkg/transformers/shared"
)
type Converter interface {
Convert(contractAddress string, contractAbi string, ethLog types.Log) (TendModel, error)
}
type TendConverter struct {
BidFetcher shared.IBidFetcher
}
type TendConverter struct {}
func NewTendConverter() TendConverter {
return TendConverter{}