Skip to content
This repository has been archived by the owner on Dec 2, 2021. It is now read-only.

Commit

Permalink
[FAB-12903] Allow contract to contract invocations
Browse files Browse the repository at this point in the history
 - Only return burrow contract accounts that have permissions for
 contract invocations
 - no change in storing the contracts as we only store the contract
 code.

Change-Id: Iaebb3db83a271c23124d7a50d5f9bc97bc53685b
Signed-off-by: Swetha Repakula <srepaku@us.ibm.com>
Signed-off-by: Jay Guo <guojiannan1101@gmail.com>
  • Loading branch information
swetharepakula committed Dec 3, 2018
1 parent b354ec4 commit c56d7ec
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@ examples/e2e_cli/crypto-config/*
.tox/
# vscode settings
.vscode
# Node artifacts from installing web3 for integration tests
node_modules
package-lock.json
2 changes: 1 addition & 1 deletion Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 58 additions & 7 deletions integration/e2e/e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ const LongEventualTimeout = time.Minute

var _ = Describe("EndToEnd", func() {
var (
testDir string
client *docker.Client
network *nwo.Network
chaincode nwo.Chaincode
process ifrit.Process
zeroAddress = "0000000000000000000000000000000000000000"
SimpleStorage = helpers.SimpleStorageContract()
testDir string
client *docker.Client
network *nwo.Network
chaincode nwo.Chaincode
process ifrit.Process
zeroAddress = "0000000000000000000000000000000000000000"
SimpleStorage = helpers.SimpleStorageContract()
InvokeContract = helpers.InvokeContract()
)

BeforeEach(func() {
Expand Down Expand Up @@ -136,5 +137,55 @@ var _ = Describe("EndToEnd", func() {
output, _ = sess.Command.CombinedOutput()
fmt.Println(string(output))
Expect(sess.Out).To(gbytes.Say("0000000000000000000000000000000000000000000000000000000000000003"))

By("deploying an InvokeContract to invoke SimpleStorage")
sess, err = network.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
ChannelID: "testchannel",
Orderer: network.OrdererAddress(orderer, nwo.ListenPort),
Name: "evmcc",
Ctor: fmt.Sprintf(`{"Args":["%s","%s"]}`, zeroAddress, InvokeContract.CompiledBytecode+"000000000000000000000000"+contractAddr),
PeerAddresses: []string{
network.PeerAddress(network.Peer("Org1", "peer0"), nwo.ListenPort),
network.PeerAddress(network.Peer("Org2", "peer1"), nwo.ListenPort),
},
WaitForEvent: true,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, LongEventualTimeout).Should(gexec.Exit(0))
Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))

output = sess.Err.Contents()
invokeAddr := string(regexp.MustCompile(`Chaincode invoke successful. result: status:200 payload:"([0-9a-fA-F]{40})"`).FindSubmatch(output)[1])
Expect(invokeAddr).ToNot(BeEmpty())

By("invoking SimpleStorage through the InvokeContract")
sess, err = network.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
ChannelID: "testchannel",
Orderer: network.OrdererAddress(orderer, nwo.ListenPort),
Name: "evmcc",
//InvokeContract.setVal(8) which will cause SimpleStorage.set(8) to be invoked.
Ctor: fmt.Sprintf(`{"Args":["%s","%s0000000000000000000000000000000000000000000000000000000000000008"]}`, invokeAddr, InvokeContract.FunctionHashes["setVal"]),
PeerAddresses: []string{
network.PeerAddress(network.Peer("Org1", "peer0"), nwo.ListenPort),
network.PeerAddress(network.Peer("Org2", "peer1"), nwo.ListenPort),
},
WaitForEvent: true,
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, LongEventualTimeout).Should(gexec.Exit(0))
Expect(sess.Err).To(gbytes.Say("Chaincode invoke successful. result: status:200"))

By("querying the SimpleStorage smart contract")
sess, err = network.PeerUserSession(peer, "User1", helpers.ChaincodeQueryWithHex{
ChannelID: "testchannel",
Name: "evmcc",
//get()
Ctor: fmt.Sprintf(`{"Args":["%s","%s"]}`, contractAddr, SimpleStorage.FunctionHashes["get"]),
})
Expect(err).NotTo(HaveOccurred())
Eventually(sess, LongEventualTimeout).Should(gexec.Exit(0))
output, _ = sess.Command.CombinedOutput()
fmt.Println(string(output))
Expect(sess.Out).To(gbytes.Say("0000000000000000000000000000000000000000000000000000000000000008"))
})
})
38 changes: 38 additions & 0 deletions integration/helpers/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,41 @@ func SimpleStorageContract() Contract {
FunctionHashes: functionHashes,
}
}

func InvokeContract() Contract {
/* Invokes a previously deployed SimpleStorage Contract
pragma solidity ^0.4.18;
interface StorageInterface{
function get() external returns (uint);
function set(uint _val);
}
contract Invoke{
StorageInterface store;
constructor(StorageInterface _store) public {
store = _store;
}
function getVal() public view returns (uint result) {
return store.get();
}
function setA(uint _val) public returns (uint result) {
store.set(_val);
return _val;
}
}
*/

functionHashes := make(map[string]string)
functionHashes["getVal"] = "e1cb0e52"
functionHashes["setVal"] = "3d4197f0"

return Contract{
CompiledBytecode: "608060405234801561001057600080fd5b50604051602080610256833981016040525160008054600160a060020a03909216600160a060020a0319909216919091179055610204806100526000396000f30060806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633d4197f08114610050578063e1cb0e521461007a575b600080fd5b34801561005c57600080fd5b5061006860043561008f565b60408051918252519081900360200190f35b34801561008657600080fd5b50610068610120565b60008054604080517f60fe47b100000000000000000000000000000000000000000000000000000000815260048101859052905173ffffffffffffffffffffffffffffffffffffffff909216916360fe47b191602480820192869290919082900301818387803b15801561010257600080fd5b505af1158015610116573d6000803e3d6000fd5b5093949350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101a757600080fd5b505af11580156101bb573d6000803e3d6000fd5b505050506040513d60208110156101d157600080fd5b50519050905600a165627a7a723058208873497fb521d304cc79b588e9adad54377e155c77b1e5b3c35f2563657fb0700029",
RuntimeBytecode: "60806040526004361061004b5763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416633d4197f08114610050578063e1cb0e521461007a575b600080fd5b34801561005c57600080fd5b5061006860043561008f565b60408051918252519081900360200190f35b34801561008657600080fd5b50610068610120565b60008054604080517f60fe47b100000000000000000000000000000000000000000000000000000000815260048101859052905173ffffffffffffffffffffffffffffffffffffffff909216916360fe47b191602480820192869290919082900301818387803b15801561010257600080fd5b505af1158015610116573d6000803e3d6000fd5b5093949350505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636d4ce63c6040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156101a757600080fd5b505af11580156101bb573d6000803e3d6000fd5b505050506040513d60208110156101d157600080fd5b50519050905600a165627a7a723058208873497fb521d304cc79b588e9adad54377e155c77b1e5b3c35f2563657fb0700029",
FunctionHashes: functionHashes,
}
}
21 changes: 19 additions & 2 deletions statemanager/statemanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,22 @@ import (

"github.com/hyperledger/burrow/account"
"github.com/hyperledger/burrow/binary"
"github.com/hyperledger/burrow/permission"
"github.com/hyperledger/burrow/permission/types"
"github.com/hyperledger/fabric/core/chaincode/shim"
)

//Permissions for contract to send CallTx or SendTx to another contract
const ContractPermFlags = permission.Call | permission.Send

var ContractPerms = types.AccountPermissions{
Base: types.BasePermissions{
Perms: ContractPermFlags,
SetBit: ContractPermFlags,
},
Roles: []string{},
}

type StateManager interface {
GetAccount(address account.Address) (account.Account, error)
GetStorage(address account.Address, key binary.Word256) (binary.Word256, error)
Expand Down Expand Up @@ -46,10 +59,14 @@ func (s *stateManager) GetAccount(address account.Address) (account.Account, err
return account.ConcreteAccount{}.Account(), nil
}

return account.ConcreteAccount{
acct := account.ConcreteAccount{
Address: address,
Code: code,
}.Account(), nil
}.MutableAccount()

//Setting permission on account to allow contract invocations and queries
acct.SetPermissions(ContractPerms)
return acct, nil
}

func (s *stateManager) GetStorage(address account.Address, key binary.Word256) (binary.Word256, error) {
Expand Down
4 changes: 3 additions & 1 deletion statemanager/statemanager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ var _ = Describe("Statemanager", func() {
expectedAcct := account.ConcreteAccount{
Address: addr,
Code: []byte("account code"),
}.Account()
}.MutableAccount()

expectedAcct.SetPermissions(statemanager.ContractPerms)

acct, err := sm.GetAccount(addr)
Expect(err).ToNot(HaveOccurred())
Expand Down

0 comments on commit c56d7ec

Please # to comment.