2023-09-12 19:14:08 +00:00
//go:build !gowaku_no_rln
// +build !gowaku_no_rln
2023-08-18 21:24:04 +00:00
package rlngenerate
import (
"context"
"errors"
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log"
"github.com/waku-org/go-waku/logging"
2023-08-31 15:49:38 +00:00
"github.com/waku-org/go-waku/waku/v2/protocol/rln/web3"
2023-08-18 21:24:04 +00:00
"github.com/waku-org/go-zerokit-rln/rln"
"go.uber.org/zap"
)
2023-08-31 15:49:38 +00:00
func getMembershipFee ( ctx context . Context , rlnContract web3 . RLNContract ) ( * big . Int , error ) {
2023-08-18 21:24:04 +00:00
return rlnContract . MEMBERSHIPDEPOSIT ( & bind . CallOpts { Context : ctx } )
}
2023-08-21 19:10:32 +00:00
func buildTransactor ( ctx context . Context , membershipFee * big . Int , chainID * big . Int ) ( * bind . TransactOpts , error ) {
2023-08-18 21:24:04 +00:00
auth , err := bind . NewKeyedTransactorWithChainID ( options . ETHPrivateKey , chainID )
if err != nil {
2023-08-21 19:10:32 +00:00
return nil , err
2023-08-18 21:24:04 +00:00
}
2023-08-21 19:10:32 +00:00
2023-08-18 21:24:04 +00:00
auth . Value = membershipFee
auth . Context = ctx
auth . GasLimit = options . ETHGasLimit
var ok bool
if options . ETHNonce != "" {
nonce := & big . Int { }
auth . Nonce , ok = nonce . SetString ( options . ETHNonce , 10 )
if ! ok {
2023-08-21 19:10:32 +00:00
return nil , errors . New ( "invalid nonce value" )
2023-08-18 21:24:04 +00:00
}
}
if options . ETHGasFeeCap != "" {
gasFeeCap := & big . Int { }
auth . GasFeeCap , ok = gasFeeCap . SetString ( options . ETHGasFeeCap , 10 )
if ! ok {
2023-08-21 19:10:32 +00:00
return nil , errors . New ( "invalid gas fee cap value" )
2023-08-18 21:24:04 +00:00
}
}
if options . ETHGasTipCap != "" {
gasTipCap := & big . Int { }
auth . GasTipCap , ok = gasTipCap . SetString ( options . ETHGasTipCap , 10 )
if ! ok {
2023-08-21 19:10:32 +00:00
return nil , errors . New ( "invalid gas tip cap value" )
2023-08-18 21:24:04 +00:00
}
}
if options . ETHGasPrice != "" {
gasPrice := & big . Int { }
auth . GasPrice , ok = gasPrice . SetString ( options . ETHGasPrice , 10 )
if ! ok {
2023-08-21 19:10:32 +00:00
return nil , errors . New ( "invalid gas price value" )
2023-08-18 21:24:04 +00:00
}
}
2023-08-21 19:10:32 +00:00
return auth , nil
}
2023-08-31 15:49:38 +00:00
func register ( ctx context . Context , web3Config * web3 . Config , idComm rln . IDCommitment ) ( rln . MembershipIndex , error ) {
2023-08-21 19:10:32 +00:00
// check if the contract exists by calling a static function
2023-08-31 15:49:38 +00:00
membershipFee , err := getMembershipFee ( ctx , web3Config . RLNContract )
2023-08-21 19:10:32 +00:00
if err != nil {
return 0 , err
}
2023-08-31 15:49:38 +00:00
auth , err := buildTransactor ( ctx , membershipFee , web3Config . ChainID )
2023-08-21 19:10:32 +00:00
if err != nil {
return 0 , err
}
2023-08-18 21:24:04 +00:00
log . Debug ( "registering an id commitment" , zap . Binary ( "idComm" , idComm [ : ] ) )
// registers the idComm into the membership contract whose address is in rlnPeer.membershipContractAddress
2023-08-31 15:49:38 +00:00
tx , err := web3Config . RegistryContract . Register ( auth , web3Config . RLNContract . StorageIndex , rln . Bytes32ToBigInt ( idComm ) )
2023-08-18 21:24:04 +00:00
if err != nil {
return 0 , fmt . Errorf ( "transaction error: %w" , err )
}
2023-08-21 19:10:32 +00:00
explorerURL := ""
2023-08-31 15:49:38 +00:00
switch web3Config . ChainID . Int64 ( ) {
2023-08-18 21:24:04 +00:00
case 1 :
2023-08-21 19:10:32 +00:00
explorerURL = "https://etherscan.io"
2023-08-18 21:24:04 +00:00
case 5 :
2023-08-21 19:10:32 +00:00
explorerURL = "https://goerli.etherscan.io"
2023-08-18 21:24:04 +00:00
case 11155111 :
2023-08-21 19:10:32 +00:00
explorerURL = "https://sepolia.etherscan.io"
2023-08-18 21:24:04 +00:00
}
2023-08-21 19:10:32 +00:00
if explorerURL != "" {
logger . Info ( fmt . Sprintf ( "transaction broadcasted, find details of your registration transaction in %s/tx/%s" , explorerURL , tx . Hash ( ) ) )
2023-08-18 21:24:04 +00:00
} else {
logger . Info ( "transaction broadcasted." , zap . String ( "transactionHash" , tx . Hash ( ) . String ( ) ) )
}
logger . Warn ( "waiting for transaction to be mined..." )
2023-08-31 15:49:38 +00:00
txReceipt , err := bind . WaitMined ( ctx , web3Config . ETHClient , tx )
2023-08-18 21:24:04 +00:00
if err != nil {
return 0 , fmt . Errorf ( "transaction error: %w" , err )
}
if txReceipt . Status != types . ReceiptStatusSuccessful {
return 0 , errors . New ( "transaction reverted" )
}
// the receipt topic holds the hash of signature of the raised events
2023-08-31 15:49:38 +00:00
evt , err := web3Config . RLNContract . ParseMemberRegistered ( * txReceipt . Logs [ 0 ] )
2023-08-18 21:24:04 +00:00
if err != nil {
return 0 , err
}
2023-08-21 19:10:32 +00:00
var eventIDComm rln . IDCommitment = rln . BigIntToBytes32 ( evt . IdCommitment )
2023-08-18 21:24:04 +00:00
2023-11-09 11:40:19 +00:00
log . Debug ( "information extracted from tx log" , zap . Uint64 ( "blockNumber" , evt . Raw . BlockNumber ) , logging . HexBytes ( "idCommitment" , eventIDComm [ : ] ) , zap . Uint64 ( "index" , evt . Index . Uint64 ( ) ) )
2023-08-18 21:24:04 +00:00
if eventIDComm != idComm {
return 0 , errors . New ( "invalid id commitment key" )
}
return rln . MembershipIndex ( uint ( evt . Index . Int64 ( ) ) ) , nil
}