package ethclient import ( "context" "math/big" "github.com/Secured-Finance/dione/contracts/aggregator" "github.com/Secured-Finance/dione/contracts/dioneStaking" stakingContract "github.com/Secured-Finance/dione/contracts/dioneStaking" oracleEmitter "github.com/Secured-Finance/dione/contracts/oracleemitter" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/event" ) // TODO: change artifacts for other contracts type EthereumClient struct { client *ethclient.Client ethAddress *common.Address authTransactor *bind.TransactOpts oracleEmitter *oracleEmitter.OracleEmitterSession aggregator *aggregator.AggregatorSession dioneStaking *stakingContract.DioneStakingSession // dioneOracle *dioneOracle.DioneOracleSession } type OracleEvent struct { RequestType string CallbackAddress common.Address CallbackMethodID [4]byte RequestID *big.Int } type Ethereum interface { Initialize(ctx context.Context, url, connectionType, privateKey, oracleEmitterContractAddress, aggregatorContractAddress string) error Balance(context.Context, string) (*big.Int, error) SubscribeOnSmartContractEvents(context.Context, string) SubmitRequestAnswer(reqID *big.Int, data string, callbackAddress common.Address, callbackMethodID [4]byte) error } func NewEthereumClient() *EthereumClient { ethereumClient := &EthereumClient{} return ethereumClient } func (c *EthereumClient) Initialize(ctx context.Context, url, privateKey, oracleEmitterContractAddress, aggregatorContractAddress, dioneStakingAddress string) error { client, err := ethclient.Dial(url) if err != nil { return err } c.client = client ecdsaKey, err := crypto.HexToECDSA(privateKey) if err != nil { return err } authTransactor := bind.NewKeyedTransactor(ecdsaKey) c.authTransactor = authTransactor c.ethAddress = &c.authTransactor.From emitter, err := oracleEmitter.NewOracleEmitter(common.HexToAddress(oracleEmitterContractAddress), client) if err != nil { return err } aggregatorPlainSC, err := aggregator.NewAggregator(common.HexToAddress(aggregatorContractAddress), client) if err != nil { return err } stakingContract, err := dioneStaking.NewDioneStaking(common.HexToAddress(dioneStakingAddress), client) if err != nil { return err } // oracleContract, err := dioneOracle.NewDioneOracle(common.HexToAddress(dioneOracleContract), client) // if err != nil { // return err // } c.oracleEmitter = &oracleEmitter.OracleEmitterSession{ Contract: emitter, CallOpts: bind.CallOpts{ Pending: true, From: authTransactor.From, Context: context.Background(), }, TransactOpts: bind.TransactOpts{ From: authTransactor.From, Signer: authTransactor.Signer, GasLimit: 200000, // 0 automatically estimates gas limit GasPrice: nil, // nil automatically suggests gas price Context: context.Background(), }, } c.aggregator = &aggregator.AggregatorSession{ Contract: aggregatorPlainSC, CallOpts: bind.CallOpts{ Pending: true, From: authTransactor.From, Context: context.Background(), }, TransactOpts: bind.TransactOpts{ From: authTransactor.From, Signer: authTransactor.Signer, GasLimit: 200000, // 0 automatically estimates gas limit GasPrice: nil, // nil automatically suggests gas price Context: context.Background(), }, } c.dioneStaking = &dioneStaking.DioneStakingSession{ Contract: stakingContract, CallOpts: bind.CallOpts{ Pending: true, From: authTransactor.From, Context: context.Background(), }, TransactOpts: bind.TransactOpts{ From: authTransactor.From, Signer: authTransactor.Signer, GasLimit: 200000, // 0 automatically estimates gas limit GasPrice: big.NewInt(1860127603), // nil automatically suggests gas price Context: context.Background(), }, } // c.dioneOracle = &dioneOracle.DioneOracleSession{ // Contract: oracleContract, // CallOpts: bind.CallOpts{ // Pending: true, // From: authTransactor.From, // Context: context.Background(), // }, // TransactOpts: bind.TransactOpts{ // From: authTransactor.From, // Signer: authTransactor.Signer, // GasLimit: 200000, // 0 automatically estimates gas limit // GasPrice: big.NewInt(1860127603), // nil automatically suggests gas price // Context: context.Background(), // }, // } return nil } func (c *EthereumClient) GetEthAddress() *common.Address { return c.ethAddress } func (c *EthereumClient) SubscribeOnOracleEvents(ctx context.Context) (chan *oracleEmitter.OracleEmitterNewOracleRequest, event.Subscription, error) { resChan := make(chan *oracleEmitter.OracleEmitterNewOracleRequest) requestsFilter := c.oracleEmitter.Contract.OracleEmitterFilterer subscription, err := requestsFilter.WatchNewOracleRequest(&bind.WatchOpts{ Start: nil, //last block Context: ctx, }, resChan) if err != nil { return nil, nil, err } return resChan, subscription, err } // func (c *EthereumClient) SubscribeOnSumbittedRequests(ctx context.Context) (chan *dioneOracle.DioneOracleSubmittedOracleRequest, event.Subscription, error) { // resChan := make(chan *dioneOracle.DioneOracleSubmittedOracleRequest) // requestsFilter := c.dioneOracle.Contract.DioneOracleFilterer // subscription, err := requestsFilter.WatchSubmittedOracleRequest(&bind.WatchOpts{ // Start: nil, //last block // Context: ctx, // }, resChan) // if err != nil { // return nil, nil, err // } // return resChan, subscription, err // } func (c *EthereumClient) SubmitRequestAnswer(reqID *big.Int, data string, callbackAddress common.Address) error { _, err := c.aggregator.CollectData(reqID, data, callbackAddress) if err != nil { return err } return nil }