Skip to content

Commit

Permalink
Merge pull request #204 from kaleido-io/erc1155
Browse files Browse the repository at this point in the history
Fixes for ERC-1155 with evmconnect
  • Loading branch information
nguyer authored Aug 24, 2022
2 parents be0bfee + 948026a commit c2dfa29
Show file tree
Hide file tree
Showing 11 changed files with 202 additions and 372 deletions.
13 changes: 10 additions & 3 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ var initCmd = &cobra.Command{
if err := validateBlockchainProvider(blockchainProviderInput, blockchainNodeProviderInput); err != nil {
return err
}
if err := validateTokensProvider(tokenProvidersSelection); err != nil {
if err := validateTokensProvider(tokenProvidersSelection, blockchainNodeProviderInput); err != nil {
return err
}
if err := validateReleaseChannel(releaseChannelInput); err != nil {
Expand Down Expand Up @@ -186,11 +186,18 @@ func validateBlockchainProvider(providerString, nodeString string) error {
return nil
}

func validateTokensProvider(input []string) error {
_, err := types.TokenProvidersFromStrings(input)
func validateTokensProvider(input []string, blockchainNodeProviderInput string) error {
tokenProviders, err := types.TokenProvidersFromStrings(input)
if err != nil {
return err
}
if blockchainNodeProviderInput == types.RemoteRPC.String() {
for _, t := range tokenProviders {
if t == types.ERC1155 {
return errors.New("erc1155 is currently not supported with a remote-rpc node")
}
}
}
return nil
}

Expand Down
183 changes: 7 additions & 176 deletions internal/blockchain/ethereum/connector/ethconnect/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,10 @@
package ethconnect

import (
"bytes"
"context"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"net/http"
"net/url"
"path"
"strings"
Expand Down Expand Up @@ -64,6 +58,7 @@ type EthconnectMessageRequest struct {
From string `json:"from,omitempty"`
ABI interface{} `json:"abi,omitempty"`
Bytecode string `json:"compiled"`
Params []interface{} `json:"params"`
}

type EthconnectMessageHeaders struct {
Expand Down Expand Up @@ -107,137 +102,6 @@ func (e *Ethconnect) Port() int {
return 8080
}

func publishABI(ethconnectUrl string, contract *ethtypes.CompiledContract) (*PublishAbiResponseBody, error) {
u, err := url.Parse(ethconnectUrl)
if err != nil {
return nil, err
}
u, err = u.Parse("abis")
if err != nil {
return nil, err
}
requestUrl := u.String()
abi, err := json.Marshal(contract.ABI)
if err != nil {
return nil, err
}
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
fw, err := writer.CreateFormField("abi")
if err != nil {
return nil, err
}
if _, err := io.Copy(fw, bytes.NewReader(abi)); err != nil {
return nil, err
}
fw, err = writer.CreateFormField("bytecode")
if err != nil {
return nil, err
}
if _, err = io.Copy(fw, strings.NewReader(contract.Bytecode)); err != nil {
return nil, err
}
writer.Close()
req, err := http.NewRequest("POST", requestUrl, bytes.NewReader(body.Bytes()))
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", writer.FormDataContentType())
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("%s [%d] %s", req.URL, resp.StatusCode, responseBody)
}
var publishAbiResponse *PublishAbiResponseBody
json.Unmarshal(responseBody, &publishAbiResponse)
return publishAbiResponse, nil
}

func deprecatedDeployContract(ethconnectUrl string, abiId string, fromAddress string, params map[string]string, registeredName string) (*DeployContractResponseBody, error) {
u, err := url.Parse(ethconnectUrl)
if err != nil {
return nil, err
}
u, err = u.Parse(path.Join("abis", abiId))
if err != nil {
return nil, err
}
requestUrl := u.String()
requestBody, err := json.Marshal(params)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(requestBody))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-firefly-from", fromAddress)
req.Header.Set("x-firefly-sync", "true")
if registeredName != "" {
req.Header.Set("x-firefly-register", registeredName)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != 200 {
return nil, fmt.Errorf("%s [%d] %s", req.URL, resp.StatusCode, responseBody)
}
var deployContractResponse *DeployContractResponseBody
json.Unmarshal(responseBody, &deployContractResponse)
return deployContractResponse, nil
}

func deprecatedRegisterContract(ethconnectUrl string, abiId string, contractAddress string, fromAddress string, registeredName string, params map[string]string) (*RegisterResponseBody, error) {
u, err := url.Parse(ethconnectUrl)
if err != nil {
return nil, err
}
u, err = u.Parse(path.Join("abis", abiId, contractAddress))
if err != nil {
return nil, err
}
requestUrl := u.String()
req, err := http.NewRequest("POST", requestUrl, bytes.NewBuffer(nil))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("x-firefly-sync", "true")
req.Header.Set("x-firefly-register", registeredName)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
responseBody, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if resp.StatusCode != 201 {
return nil, fmt.Errorf("%s [%d] %s", req.URL, resp.StatusCode, responseBody)
}
var registerResponseBody *RegisterResponseBody
json.Unmarshal(responseBody, &registerResponseBody)
return registerResponseBody, nil
}

func (e *Ethconnect) DeployContract(contract *ethtypes.CompiledContract, contractName string, member *types.Organization, extraArgs []string) (*types.ContractDeploymentResult, error) {
ethconnectUrl := fmt.Sprintf("http://127.0.0.1:%v", member.ExposedConnectorPort)
address := member.Account.(*ethereum.Account).Address
Expand All @@ -247,13 +111,19 @@ func (e *Ethconnect) DeployContract(contract *ethtypes.CompiledContract, contrac
}
base64Bytecode := base64.StdEncoding.EncodeToString(hexBytecode)

params := make([]interface{}, len(extraArgs))
for i, arg := range extraArgs {
params[i] = arg
}

requestBody := &EthconnectMessageRequest{
Headers: EthconnectMessageHeaders{
Type: "DeployContract",
},
From: address,
ABI: contract.ABI,
Bytecode: base64Bytecode,
Params: params,
}

ethconnectResponse := &EthconnectMessageResponse{}
Expand All @@ -277,45 +147,6 @@ func (e *Ethconnect) DeployContract(contract *ethtypes.CompiledContract, contrac
return result, nil
}

func DeprecatedDeployContract(member *types.Organization, contract *ethtypes.CompiledContract, name string, args map[string]string) (string, error) {
ethconnectUrl := fmt.Sprintf("http://127.0.0.1:%v", member.ExposedConnectorPort)
abiResponse, err := publishABI(ethconnectUrl, contract)
address := member.Account.(*ethereum.Account).Address
if err != nil {
return "", err
}
deployResponse, err := deprecatedDeployContract(ethconnectUrl, abiResponse.ID, address, args, name)
if err != nil {
return "", err
}
return deployResponse.ContractAddress, nil
}

func DeprecatedRegisterContract(member *types.Organization, contract *ethtypes.CompiledContract, contractAddress string, name string, args map[string]string) error {
ethconnectUrl := fmt.Sprintf("http://127.0.0.1:%v", member.ExposedConnectorPort)
abiResponse, err := publishABI(ethconnectUrl, contract)
address := member.Account.(*ethereum.Account).Address
if err != nil {
return err
}
_, err = deprecatedRegisterContract(ethconnectUrl, abiResponse.ID, contractAddress, address, name, args)
if err != nil {
return err
}
return nil
}

// func DeployCustomContract(member *types.Organization, filename, contractName string) (string, error) {
// contracts, err := ethereum.ReadContractJSON(filename)
// if err != nil {
// return "", nil
// }

// contract := contracts.Contracts[contractName]

// return deployContract(member, contract, map[string]string{})
// }

func getReply(ctx context.Context, ethconnectUrl, id string) (*EthconnectReply, error) {
u, err := url.Parse(ethconnectUrl)
if err != nil {
Expand Down
7 changes: 7 additions & 0 deletions internal/blockchain/ethereum/connector/evmconnect/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type EvmconnectRequest struct {
From string `json:"from,omitempty"`
Definition interface{} `json:"definition,omitempty"`
Contract string `json:"contract,omitempty"`
Params []interface{} `json:"params,omitempty"`
}

type EvmconnectHeaders struct {
Expand Down Expand Up @@ -77,13 +78,19 @@ func (e *Evmconnect) DeployContract(contract *ethtypes.CompiledContract, contrac
evmconnectURL := fmt.Sprintf("http://127.0.0.1:%v", member.ExposedConnectorPort)
fromAddress := member.Account.(*ethereum.Account).Address

params := make([]interface{}, len(extraArgs))
for i, arg := range extraArgs {
params[i] = arg
}

requestBody := &EvmconnectRequest{
Headers: EvmconnectHeaders{
Type: "DeployContract",
},
From: fromAddress,
Definition: contract.ABI,
Contract: contract.Bytecode,
Params: params,
}

txResponse := &EvmconnectTransactionResponse{}
Expand Down
18 changes: 16 additions & 2 deletions internal/blockchain/ethereum/remoterpc/remoterpc_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,25 @@ func (p *RemoteRPCProvider) Reset() error {
}

func (p *RemoteRPCProvider) GetContracts(filename string, extraArgs []string) ([]string, error) {
return []string{}, nil
contracts, err := ethereum.ReadContractJSON(filename)
if err != nil {
return []string{}, err
}
contractNames := make([]string, len(contracts.Contracts))
i := 0
for contractName := range contracts.Contracts {
contractNames[i] = contractName
i++
}
return contractNames, err
}

func (p *RemoteRPCProvider) DeployContract(filename, contractName, instanceName string, member *types.Organization, extraArgs []string) (*types.ContractDeploymentResult, error) {
return nil, fmt.Errorf("contract deployment not supported for Remote RPC URL connections")
contracts, err := ethereum.ReadContractJSON(filename)
if err != nil {
return nil, err
}
return p.connector.DeployContract(contracts.Contracts[contractName], instanceName, member, extraArgs)
}

func (p *RemoteRPCProvider) CreateAccount(args []string) (interface{}, error) {
Expand Down
22 changes: 19 additions & 3 deletions internal/docker/docker_checks.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
// Copyright © 2022 Kaleido, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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 docker

import (
Expand All @@ -11,20 +27,20 @@ func CheckDockerConfig() error {
dockerCmd := exec.Command("docker", "-v")
_, err := dockerCmd.Output()
if err != nil {
return fmt.Errorf("An error occurred while running docker. Is docker installed on your computer?")
return fmt.Errorf("an error occurred while running docker. Is docker installed on your computer?")
}

dockerComposeCmd := exec.Command("docker-compose", "-v")
_, err = dockerComposeCmd.Output()

if err != nil {
return fmt.Errorf("An error occurred while running docker-compose. Is docker-compose installed on your computer?")
return fmt.Errorf("an error occurred while running docker-compose. Is docker-compose installed on your computer?")
}

dockerDeamonCheck := exec.Command("docker", "ps")
_, err = dockerDeamonCheck.Output()
if err != nil {
return fmt.Errorf("An error occurred while running docker. Is docker running on your computer?")
return fmt.Errorf("an error occurred while running docker. Is docker running on your computer?")
}

return nil
Expand Down
Loading

0 comments on commit c2dfa29

Please sign in to comment.