github.com/0chain/gosdk@v1.17.11/znft/znft.go (about) 1 package znft 2 3 import ( 4 "context" 5 "fmt" 6 "os" 7 8 "github.com/0chain/gosdk/core/logger" 9 10 storageerc721 "github.com/0chain/gosdk/znft/contracts/dstorageerc721/binding" 11 storageerc721fixed "github.com/0chain/gosdk/znft/contracts/dstorageerc721fixed/binding" 12 storageerc721pack "github.com/0chain/gosdk/znft/contracts/dstorageerc721pack/binding" 13 storageerc721random "github.com/0chain/gosdk/znft/contracts/dstorageerc721random/binding" 14 15 factoryerc721 "github.com/0chain/gosdk/znft/contracts/factorymoduleerc721/binding" 16 factoryerc721fixed "github.com/0chain/gosdk/znft/contracts/factorymoduleerc721fixed/binding" 17 factoryerc721pack "github.com/0chain/gosdk/znft/contracts/factorymoduleerc721pack/binding" 18 factoryerc721random "github.com/0chain/gosdk/znft/contracts/factorymoduleerc721random/binding" 19 20 "github.com/ethereum/go-ethereum/accounts/abi/bind" 21 "github.com/ethereum/go-ethereum/common" 22 "github.com/pkg/errors" 23 ) 24 25 var defaultLogLevel = logger.DEBUG 26 var Logger logger.Logger 27 28 const ( 29 ConfigFile = "config.yaml" 30 WalletDir = "wallets" 31 ) 32 33 type Configuration struct { 34 FactoryAddress string // FactoryAddress address 35 FactoryModuleERC721Address string // FactoryModuleERC721Address address 36 FactoryModuleERC721PackedAddress string // FactoryModuleERC721PackedAddress address 37 FactoryModuleERC721FixedAddress string // FactoryModuleERC721FixedAddress address 38 FactoryModuleERC721RandomAddress string // FactoryModuleERC721RandomAddress address 39 EthereumNodeURL string // EthereumNodeURL URL of ethereum RPC node (infura or alchemy) 40 WalletAddress string // WalletAddress client address 41 VaultPassword string // VaultPassword used to sign transactions on behalf of the client 42 Homedir string // Homedir is a client config folder 43 Value int64 // Value to execute Ethereum smart contracts (default = 0) 44 } 45 46 type Znft struct { 47 cfg *Configuration 48 } 49 50 func init() { 51 Logger.Init(defaultLogLevel, "0chain-znft-sdk") 52 } 53 54 func NewNFTApplication(c *Configuration) *Znft { 55 return &Znft{c} 56 } 57 58 func GetConfigDir() string { 59 var configDir string 60 home, err := os.UserHomeDir() 61 if err != nil { 62 fmt.Println(err) 63 os.Exit(1) 64 } 65 configDir = home + "/.zcn" 66 return configDir 67 } 68 69 // Functions used by session factories to create session 70 71 func (app *Znft) constructFactoryERC721(ctx context.Context, address string) (*factoryerc721.Binding, *bind.TransactOpts, error) { 72 storage, err := app.createFactoryERC721(address) 73 if err != nil { 74 return nil, nil, errors.Wrapf(err, "failed to construct %s", "FactoryERC721") 75 } 76 77 transaction, err := app.createTransactOpts(ctx) 78 79 return storage, transaction, err 80 } 81 82 func (app *Znft) constructFactoryERC721Fixed(ctx context.Context, address string) (*factoryerc721fixed.Binding, *bind.TransactOpts, error) { 83 storage, err := app.createFactoryERC721Fixed(address) 84 if err != nil { 85 return nil, nil, errors.Wrapf(err, "failed to construct %s", "FactoryERC721Fixed") 86 } 87 88 transaction, err := app.createTransactOpts(ctx) 89 90 return storage, transaction, err 91 } 92 93 func (app *Znft) constructFactoryERC721Pack(ctx context.Context, address string) (*factoryerc721pack.Binding, *bind.TransactOpts, error) { 94 storage, err := app.createFactoryERC721Pack(address) 95 if err != nil { 96 return nil, nil, errors.Wrapf(err, "failed to construct %s", "FactoryERC721Pack") 97 } 98 99 transaction, err := app.createTransactOpts(ctx) 100 101 return storage, transaction, err 102 } 103 104 func (app *Znft) constructFactoryERC721Random(ctx context.Context, address string) (*factoryerc721random.Binding, *bind.TransactOpts, error) { 105 storage, err := app.createFactoryERC721Random(address) 106 if err != nil { 107 return nil, nil, errors.Wrapf(err, "failed to construct %s", "FactoryERC721Random") 108 } 109 110 transaction, err := app.createTransactOpts(ctx) 111 112 return storage, transaction, err 113 } 114 115 func (app *Znft) constructStorageERC721Random(ctx context.Context, address string) (*storageerc721random.Binding, *bind.TransactOpts, error) { 116 storage, err := app.createStorageERC721Random(address) 117 if err != nil { 118 return nil, nil, errors.Wrapf(err, "failed to construct %s", ContractStorageERC721RandomName) 119 } 120 121 transaction, err := app.createTransactOpts(ctx) 122 123 return storage, transaction, err 124 } 125 126 func (app *Znft) constructStorageERC721Pack(ctx context.Context, address string) (*storageerc721pack.Binding, *bind.TransactOpts, error) { 127 storage, err := app.createStorageERC721Pack(address) 128 if err != nil { 129 return nil, nil, errors.Wrapf(err, "failed to construct %s", ContractStorageERC721PackName) 130 } 131 132 transaction, err := app.createTransactOpts(ctx) 133 134 return storage, transaction, err 135 } 136 137 func (app *Znft) constructStorageERC721Fixed(ctx context.Context, address string) (*storageerc721fixed.Binding, *bind.TransactOpts, error) { 138 storage, err := app.createStorageERC721Fixed(address) 139 if err != nil { 140 return nil, nil, errors.Wrapf(err, "failed to construct %s", ContractStorageERC721FixedName) 141 } 142 143 transaction, err := app.createTransactOpts(ctx) 144 145 return storage, transaction, err 146 } 147 148 func (app *Znft) constructStorageERC721(ctx context.Context, address string) (*storageerc721.Binding, *bind.TransactOpts, error) { 149 storage, err := app.createStorageERC721(address) 150 if err != nil { 151 return nil, nil, errors.Wrapf(err, "failed to construct %s", ContractStorageERC721Name) 152 } 153 154 transaction, err := app.createTransactOpts(ctx) 155 156 return storage, transaction, err 157 } 158 159 // Used to create StorageERC721 with preliminary gas estimation 160 func (app *Znft) constructWithEstimation( //nolint 161 ctx context.Context, 162 address string, 163 method string, 164 params ...interface{}, 165 ) (*storageerc721.Binding, *bind.TransactOpts, error) { 166 erc721, err := app.createStorageERC721(address) 167 if err != nil { 168 return nil, nil, errors.Wrapf(err, "failed to create %s in method: %s", ContractStorageERC721Name, method) 169 } 170 171 transaction, err := app.createTransactOptsWithEstimation(ctx, address, method, params) 172 173 return erc721, transaction, err 174 } 175 176 // Create transaction opts with sender signature 177 func (app *Znft) createTransactOpts(ctx context.Context) (*bind.TransactOpts, error) { 178 transaction, err := app.createTransaction(ctx) 179 if err != nil { 180 return nil, errors.Wrapf(err, "failed to create createTransactOpts in %s", ContractStorageERC721Name) 181 } 182 183 return transaction, nil 184 } 185 186 func (app *Znft) createTransactOptsWithEstimation( //nolint 187 ctx context.Context, 188 address, method string, 189 params ...interface{}, 190 ) (*bind.TransactOpts, error) { 191 // Get ABI of the contract 192 abi, err := storageerc721.BindingMetaData.GetAbi() 193 if err != nil { 194 return nil, errors.Wrapf(err, "failed to get ABI in %s, method: %s", ContractStorageERC721Name, method) 195 } 196 197 // Pack the method arguments 198 pack, err := abi.Pack(method, params...) 199 if err != nil { 200 return nil, errors.Wrapf(err, "failed to pack arguments in %s, method: %s", ContractStorageERC721Name, method) 201 } 202 203 transaction, err := app.createTransactionWithGasPrice(ctx, address, pack) 204 if err != nil { 205 return nil, errors.Wrapf(err, "failed to create createTransaction in %s, method: %s", ContractStorageERC721Name, method) 206 } 207 208 return transaction, nil 209 } 210 211 // Session factories 212 213 // Factory Sessions 214 215 func (app *Znft) CreateFactoryERC721Session(ctx context.Context, addr string) (IFactoryERC721, error) { 216 contract, transact, err := app.constructFactoryERC721(ctx, addr) 217 if err != nil { 218 return nil, err 219 } 220 221 session := &factoryerc721.BindingSession{ 222 Contract: contract, 223 CallOpts: bind.CallOpts{ 224 Pending: true, 225 From: transact.From, 226 Context: ctx, 227 }, 228 TransactOpts: *transact, 229 } 230 231 storage := &FactoryERC721{ 232 session: session, 233 ctx: ctx, 234 } 235 236 return storage, nil 237 } 238 239 func (app *Znft) CreateFactoryERC721PackSession(ctx context.Context, addr string) (IFactoryPack, error) { 240 contract, transact, err := app.constructFactoryERC721Pack(ctx, addr) 241 if err != nil { 242 return nil, err 243 } 244 245 session := &factoryerc721pack.BindingSession{ 246 Contract: contract, 247 CallOpts: bind.CallOpts{ 248 Pending: true, 249 From: transact.From, 250 Context: ctx, 251 }, 252 TransactOpts: *transact, 253 } 254 255 storage := &FactoryPack{ 256 session: session, 257 ctx: ctx, 258 } 259 260 return storage, nil 261 } 262 263 func (app *Znft) CreateFactoryERC721FixedSession(ctx context.Context, addr string) (IFactoryFixed, error) { 264 contract, transact, err := app.constructFactoryERC721Fixed(ctx, addr) 265 if err != nil { 266 return nil, err 267 } 268 269 session := &factoryerc721fixed.BindingSession{ 270 Contract: contract, 271 CallOpts: bind.CallOpts{ 272 Pending: true, 273 From: transact.From, 274 Context: ctx, 275 }, 276 TransactOpts: *transact, 277 } 278 279 storage := &FactoryFixed{ 280 session: session, 281 ctx: ctx, 282 } 283 284 return storage, nil 285 } 286 287 func (app *Znft) CreateFactoryERC721RandomSession(ctx context.Context, addr string) (IFactoryRandom, error) { 288 contract, transact, err := app.constructFactoryERC721Random(ctx, addr) 289 if err != nil { 290 return nil, err 291 } 292 293 session := &factoryerc721random.BindingSession{ 294 Contract: contract, 295 CallOpts: bind.CallOpts{ 296 Pending: true, 297 From: transact.From, 298 Context: ctx, 299 }, 300 TransactOpts: *transact, 301 } 302 303 storage := &FactoryRandom{ 304 session: session, 305 ctx: ctx, 306 } 307 308 return storage, nil 309 } 310 311 // Storage Sessions 312 313 func (app *Znft) CreateStorageERC721PackSession(ctx context.Context, addr string) (IStorageECR721Pack, error) { 314 contract, transact, err := app.constructStorageERC721Pack(ctx, addr) 315 if err != nil { 316 return nil, err 317 } 318 319 session := &storageerc721pack.BindingSession{ 320 Contract: contract, 321 CallOpts: bind.CallOpts{ 322 Pending: true, 323 From: transact.From, 324 Context: ctx, 325 }, 326 TransactOpts: *transact, 327 } 328 329 storage := &StorageECR721Pack{ 330 session: session, 331 ctx: ctx, 332 } 333 334 return storage, nil 335 } 336 337 func (app *Znft) CreateStorageERC721RandomSession(ctx context.Context, addr string) (IStorageECR721Random, error) { 338 contract, transact, err := app.constructStorageERC721Random(ctx, addr) 339 if err != nil { 340 return nil, err 341 } 342 343 session := &storageerc721random.BindingSession{ 344 Contract: contract, 345 CallOpts: bind.CallOpts{ 346 Pending: true, 347 From: transact.From, 348 Context: ctx, 349 }, 350 TransactOpts: *transact, 351 } 352 353 storage := &StorageECR721Random{ 354 session: session, 355 ctx: ctx, 356 } 357 358 return storage, nil 359 } 360 361 func (app *Znft) CreateStorageERC721FixedSession(ctx context.Context, addr string) (IStorageECR721Fixed, error) { 362 contract, transact, err := app.constructStorageERC721Fixed(ctx, addr) 363 if err != nil { 364 return nil, err 365 } 366 367 session := &storageerc721fixed.BindingSession{ 368 Contract: contract, 369 CallOpts: bind.CallOpts{ 370 Pending: true, 371 From: transact.From, 372 Context: ctx, 373 }, 374 TransactOpts: *transact, 375 } 376 377 storage := &StorageECR721Fixed{ 378 session: session, 379 ctx: ctx, 380 } 381 382 return storage, nil 383 } 384 385 func (app *Znft) CreateStorageERC721Session(ctx context.Context, addr string) (IStorageECR721, error) { 386 contract, transact, err := app.constructStorageERC721(ctx, addr) 387 if err != nil { 388 return nil, err 389 } 390 391 session := &storageerc721.BindingSession{ 392 Contract: contract, 393 CallOpts: bind.CallOpts{ 394 Pending: true, 395 From: transact.From, 396 Context: ctx, 397 }, 398 TransactOpts: *transact, 399 } 400 401 storage := &StorageECR721{ 402 session: session, 403 ctx: ctx, 404 } 405 406 return storage, nil 407 } 408 409 // Binding factories 410 411 func (app *Znft) createStorageERC721(address string) (*storageerc721.Binding, error) { 412 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 413 if err != nil { 414 return nil, err 415 } 416 417 addr := common.HexToAddress(address) 418 instance, err := storageerc721.NewBinding(addr, client) 419 420 return instance, err 421 } 422 423 func (app *Znft) createStorageERC721Fixed(address string) (*storageerc721fixed.Binding, error) { 424 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 425 if err != nil { 426 return nil, err 427 } 428 429 addr := common.HexToAddress(address) 430 instance, err := storageerc721fixed.NewBinding(addr, client) 431 432 return instance, err 433 } 434 435 func (app *Znft) createStorageERC721Random(address string) (*storageerc721random.Binding, error) { 436 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 437 if err != nil { 438 return nil, err 439 } 440 441 addr := common.HexToAddress(address) 442 instance, err := storageerc721random.NewBinding(addr, client) 443 444 return instance, err 445 } 446 447 func (app *Znft) createStorageERC721Pack(address string) (*storageerc721pack.Binding, error) { 448 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 449 if err != nil { 450 return nil, err 451 } 452 453 addr := common.HexToAddress(address) 454 instance, err := storageerc721pack.NewBinding(addr, client) 455 456 return instance, err 457 } 458 459 func (app *Znft) createFactoryERC721(address string) (*factoryerc721.Binding, error) { 460 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 461 if err != nil { 462 return nil, err 463 } 464 465 addr := common.HexToAddress(address) 466 instance, err := factoryerc721.NewBinding(addr, client) 467 468 return instance, err 469 } 470 471 func (app *Znft) createFactoryERC721Pack(address string) (*factoryerc721pack.Binding, error) { 472 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 473 if err != nil { 474 return nil, err 475 } 476 477 addr := common.HexToAddress(address) 478 instance, err := factoryerc721pack.NewBinding(addr, client) 479 480 return instance, err 481 } 482 483 func (app *Znft) createFactoryERC721Random(address string) (*factoryerc721random.Binding, error) { 484 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 485 if err != nil { 486 return nil, err 487 } 488 489 addr := common.HexToAddress(address) 490 instance, err := factoryerc721random.NewBinding(addr, client) 491 492 return instance, err 493 } 494 495 func (app *Znft) createFactoryERC721Fixed(address string) (*factoryerc721fixed.Binding, error) { 496 client, err := CreateEthClient(app.cfg.EthereumNodeURL) 497 if err != nil { 498 return nil, err 499 } 500 501 addr := common.HexToAddress(address) 502 instance, err := factoryerc721fixed.NewBinding(addr, client) 503 504 return instance, err 505 }