How to make smart contract private in quorum - blockchain

In the 7nodes example (https://github.com/jpmorganchase/quorum-examples/tree/master/examples/7nodes ) for quorum, the smart contract that is deployed is a private contract between node1 and node7. To make it private the script file author used public key passed by private key."sending of a private transaction to generate a (private) smart contract (SimpleStorage) sent from node 1 "for" node 7 (denoted by the public key passed via privateFor: ["ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc="] in the sendTransaction call)."
How exactly the key value "ROAZBWtSacxXQrOe3FGAqJDyJjFePR5ce4TSIzmJ0Bc=" was generated i could not understand?
Also, after the completion of the JS file script1.js, it gave me the Contract transaction send: TransactionHash", and i never got the contract address.
When will the contract address come after the mining is completed ?
How do i recognise that this address is my smart contract address ?

The keys are already generated for the nodes.
When you spin up the environment, each node is assigned a predefined dummy public keys.
this can be found at location : \quorum-examples\examples\7nodes\keys

In 7Nodes example you can see the 256bit private key in raft/nodekey* files and the corresponding 512bit public key in nodename (enode) text in static-nodes.json. Use bootnode to create private and public key pairs. And use constellation-node to generate .pub and .key files.

To answer the second part of your question, to get the contract address you can use eth.getTransactionReceipt(__); and copy the txHash you get (quoted) into the blank.
Then the contract address should come up in one of the fields returned.
Check out this page for more info/details.

The key used here is the public key of transaction manager which is respobsible for sending and receiving private transactions in addition to encrypting communications. You can find this key in file named tm.pub inside data folder of the node alongside its associated private key in file tm.key.

Related

SendTransactionAsync only works with public key

I am trying to call a function from my contract using Netherums "SendTransactionAsync", however, it only works when the source is a public key rather than a private key.
I am using Ganache private network to test my contract.
Error: One or more errors occurred. (sender account not recognized: eth_sendTransaction)
This is my Code
HexBigInteger gas = new HexBigInteger(new BigInteger(400000));
HexBigInteger value = new HexBigInteger(new BigInteger(0));
myContract.GetFunction("giveFruit").SendTransactionAsync("b6558007a470f0593a35be45926342e92942fa3d7d00fc357c104fcc428f0cee", gas, value, "apple");
The first parameter of the function is the address that is supposed to call this function and the last parameter
is an item passed to the contracts function?
The contract is working fine however when the code above doesn't work if I use the private key as shown, on the other hand, if I replace the private key with a public key it works just fine.
This doesn't make any sense, as you shouldn't be allowed to send transactions using public keys.

What Does this code mean in BEP20 token writting with Solidity

I'm trying to understand what this lines of BEP20 code mean, it is written in solidity
constructor () {
_rOwned[owner()] = _rTotal;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(0x10ED43C718714eb63d5aA57B78B54704E256024E);
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
.createPair(address(this), _uniswapV2Router.WETH());
uniswapV2Router = _uniswapV2Router;
_isExcludedFromFee[owner()] = true;
_isExcludedFromFee[address(this)] = true;
emit Transfer(address(0), owner(), _tTotal);
In the first lines, he instanciate UniswapV2Router pointing the address router to PancakeSwap. This because, he want to create a liquidity pool with his TOKEN and BNB, indeed after this instanciating operation he call createPair() that allows him to create this pair between his smart contract and the address WETH().
IMPORTANT: WETH() is a function that provider the chain native wrapped coin address where smart contract was deployed. For example: If I create a pair instanciating Uniswap router on Ethereum blockchain then WETH() will return address about WETH (Wrapping Ether) address present into Etheruem. On the contrary if I instanciate Uniswap Router with its address present into binance smart chain (and so I refers to Pancakeswap in this case), the value of WETH() will be WBNB address.
After this lines of code, I assume that he excluded from paying a fee for only transactions the owner() address (who deployed the smart contract for the first time) and smart contract itself.
Finally he emitted a Transfer event passing : address(0) (0x0000000000000000000000000000000000000000), owner() and total supply.
More information about pair on documentation.

Is it possible to make certain fields of a structure only available to contract owner?

For example, given the following structure, I want some fields to be visible only for the contract owner
struct Participant{
address participantAddress; // can be seen by anyone
string team; // can be seen by anyone
string personalDescription; // can be seen by anyone
string secret // can be seen only by contract owner
}
// Mapping each participant to an uint id
mapping(address=>Participant) public participantsMapping;
In other words, someone inspecting the participantsMapping can see all the fields EXCEPT the secret one (which can only be seen by owner)
From what I know, the "private" keyword doesn't hide any data, it's only a code-level specifier.
There are modifiers for function, but do they work for fields in a structure too? If not, how can it be achieved?
modifier onlyOwner() {
require(msg.sender==ownerAddress,
"Visible only by owner");
_;
}
No. Storing private data on-chain is impossible.
It's possible to encrypt the data, so that only the person with the secret key can access it. See https://docs.metamask.io/guide/rpc-api.html#example-4 and https://docs.metamask.io/guide/rpc-api.html#encrypting for example usage.

Where to get a signature for smart contract interaction via block explorer?

In BSC (Binance Smart Chain) contracts I often meet a signature parameter but I have no idea where to get it.
If you think that it is a signature message which you need to sign with Metamask - it's not. It's just a one of parameters of the function I need to run.
Example can be found there, just look at the purchase function and you'll see signature as a last parameter - https://bscscan.com/address/0xabc306ae80595f6c7748b81d6c2efc48b32a9e22#writeContract
Signature is a result of signing a message with a private key.
Example from the web3 docs page:
message Hello world
signed with the private key of address 0x11f4d0A3c12e86B4b5F39B213F7E19D048276DAe
results in signature 0x30755ed65396facf86c53e6217c52b4daebe72aa4941d89635409de4c9c7f9466d4e9aaec7977f05e923889b33c0d0dd27d7226b6e6f56ce737465c5cfd04be400
A contract can then verify if the signature and message (or hash of the message) can be recovered back to the signer address (cannot get the private key).
For example the OpenZeppelin ECDSA library is a developer-friendly wrapper for the low-level (EVM assembly) recovery method.
Unfortunately the contract linked in the question is passing the signature to another unspecified contract for the recovery, so I was unable to find the specific message that they're validating against and the actual recovery snippet that they're using. However, you can find more info about the signing process and on-chain recovery in this answer (the mentioned v, r and s params are literally parts of the whole signature).

How to store a hash of some data in a currently publicly available blockchain?

I have read that blockchains aren't good at storing large files. But you can create a hash of a file and somehow store that in the blockchain, they say. How do I do that? What API or service should I be looking at? Can I do it on bitcoin.org, or does it need to be some special "parameterized" blockchain service of some sort?
In the blogs I've seen touting how cool it is where you can store your data in mysql but store the hash in the blockchain, they don't show how you actually nitty-gritty get the hash into the blockchain, or even what services are recommended to do this. Where is the API? What field do I pass to the hash into?
This is what I think the frontend would look like:
hashedData = web3.utils.sha3(JSON.stringify(certificate));
contracts.mycontract.deployed().then(function(result) {
return result.createCertificate(public_addresskey,hashedData,{ from: account }); //get logged in public key from metamask
}).then(function(result) {
//send post request to backend to create db entry
}).catch(function(err) {
console.error(err);
// show error to the user.
});
The contract might look something like the sketch below.
There is a struct to contain everything but the id. A mapping from hash => Cert for random access (using the hash as id) and a certList to enumerate the certificates in case the hash isn't known. That should not happen because it emits events for each important state change. You would probably want to protect the newCert() function with onlyOwner, a whiteList or role-based access control.
To "confirm" a cert, the recipient confirms by signing a transaction. The existence of a true in this field shows that the user mentioned did indeed sign because there is no other way for this to occur.
pragma solidity 0.5.1;
contract Certificates {
struct Cert {
address recipient;
bool confirmed;
}
mapping(bytes32 => Cert) public certs;
bytes32[] public certList;
event LogNewCert(address sender, bytes32 cert, address recipient);
event LogConfirmed(address sender, bytes32 cert);
function isCert(bytes32 cert) public view returns(bool isIndeed) {
if(cert == 0) return false;
return certs[cert].recipient != address(0);
}
function createCert(bytes32 cert, address recipient) public {
require(recipient != address(0));
require(!isCert(cert));
Cert storage c = certs[cert];
c.recipient = recipient;
certList.push(cert);
emit LogNewCert(msg.sender, cert, recipient);
}
function confirmCert(bytes32 cert) public {
require(certs[cert].recipient == msg.sender);
require(certs[cert].confirmed == false);
certs[cert].confirmed = true;
emit LogConfirmed(msg.sender, cert);
}
function isUserCert(bytes32 cert, address user) public view returns(bool) {
if(!isCert(cert)) return false;
if(certs[cert].recipient != user) return false;
return certs[cert].confirmed;
}
}
The short answer is: "Use Ethereum smart contract with events and don't store hash values in the contract."
On Etherscan your may find a complete contract for the storage of hash values in Ethereum: HashValueManager. As you will see in this code example - things are a bit more complex. You have to manage access rights and here the cost was not important (this contract has been designed for a syndicated blockchain)
Actually it is very expensive to store hash data in a blockchain. When you use an Ethereum contract to store the hash data, you have to pay about 0.03 Euro (depending on the ETH and Gas prize) for each transaction.
It would be a better option not to store the hash value in the contract. A much more cheaper alternative is to emit indexed events in a smart contract and query the events (this is very fast). Information about the events are stored in a bloom filter of the mined block and will be readable forever. The only disadvantage is that an event can't be read from within the contract (but this is not your business logic)
You may read more details here about events and how to fetch them in an application : "ETHEREUM EVENT EXPLORER FOR SMART CONTRACTS" (disclaimer: this article is my blog). Also the complete source code is available on GitHub.
For store there is existing several ways. More interesting question: how would you planning to retrieve and use your data? I assume, you planning go retrieve by some way. Otherwise, if no retrieve - there is no sense to store.
OK. there is 2 ways to store your hashes. I will demonstrate examples within emercoin blockchain.
Store as OP_RETURN UTXO. To do this, use the command "createrawtransaction" by using JSON RPC API or command line interface. Just specify "data" for define UTXO, contains your hash.
In this case, data will be stored within one of unspendable transaction output. This saved data is not indexed, and you need to save TXID for future retrieval. Otherwise, you need rescan the entire blockchain for retrieve your data.
You can store data within indexed NVS-subsystem (Name-Value Storage). to upload, you need run the command "name_new", where hash can be your search key. In future, you can quickly retrieve your data by search key with commands "name_show" or "name_history". Also, there is possible to save your data as DNS-records within emerDNS, and retrieve by DNS UDP requests by protocol RFC1035.
For details, see the doc: https://emercoin.com/en/documentation/emercoin-api