I have a function that creates a valid solidity file, it's name is "makeContract". I think it's better not to post the whole function at first because it has 97 lines, but if someone asks I post. It transforms a JSON into a SOLIDITY file. What is most essential of it is below. The contract variable is a string containing the text already in solidity.
if (!existsSync(__dirname + '/temp')) await exec('mkdir '+__dirname + '/temp/')
writeFileSync(__dirname + '/temp/'+name+'.sol', contract, 'utf8')
I have another function that I called compileContract that compiles the contract, so it generates a .ABI file and another .BIN.
compileContract: async () => {
const file = readdirSync(__dirname + '/temp').filter(file => file.includes('.sol'))
await exec('solcjs --abi --bin '+ __dirname + '/temp/' + file[0] + ' -o ' + __dirname + '/temp/')
}
I still have a function that reads the .ABI file and returns it in UTF8 format.
readCompiledContract: (nameContract, extension) => {
return readFileSync(__dirname+'/temp/'+readdirSync(__dirname+'/temp/')
.find(file=>file.includes(nameContract+'.'+extension)), 'utf8')
}
I still have a function that I call garbageCollector, it simply deletes the temp folder, which was used to put the .sol, .abi and .bin files.
garbageCollector: async () => {
if (existsSync(__dirname + '/temp')) await exec('rm -rf '+__dirname+'/temp')
}
I use the code below to create a contract instance, using the functions already shown. Comments are first in English and then in Portuguese.
router.post('/create', async (req, res) => {
const { id, name, data, groupings } = req.body
// create a JSON from attributes received from body
// cria um JSON a partir dos atributos recebidos do body
const contrBody = {
name: name,
data: data,
groupings: groupings
}
try {
// rescues the user searched by ID, selects ethAddress, medicalRegisterAddress and password
// resgata o usuario procurado pelo ID, seleciona ainda ethAddress, medicalRegisterAddress e password
const user = await UserRoot.findById(id).select('+ethAddress medicalRegister password')
// effectively transforms JSON created from body attributes into a solidity file
// transforma efetivamente o JSON criado a partir dos atributos de body em um prontuário médico (arquivo solidity)
await medicalRecordContract.makeContract(contrBody)
// function that compiles the smart contract created, (see file) - no solc was used for nodejs because it has bugs
// função que compila o contrato inteligente criado, (ver arquivo) - não foi usado a solc para nodejs porque apresenta bugs
await medicalRecordContract.compileContract()
// get the ABI through the read function (see file)
// obtem a ABI por meio da função de leitura (ver arquivo)
let abi = medicalRecordContract.readCompiledContract(name, 'abi')
// create a contract by passing ABI as a parameter (see documentation https://web3js.readthedocs.io/en/v1.2.4/web3-eth-contract.html#new-contract)
// cria um contrato passando a ABI como parâmetro (ver a documentação https://web3js.readthedocs.io/en/v1.2.4/web3-eth-contract.html#new-contract)
let contract = new web3.eth.Contract(JSON.parse(abi))
return res.send({ contract: contract }) // <-- HERE <--
As you can see the code above refers to a REST API, then I make this same post that you saw in the code above, it should return an instance of contract. I am using the Insomnia program. As the full JSON has 390 lines, I am at first putting the last one, just ask me to put the full code or a specific part. Look for the Methods attribute, I tagged it with a comment so it will be easy to find.
"transactionBlockTimeout": 50,
"transactionConfirmationBlocks": 24,
"transactionPollingTimeout": 750,
"defaultAccount": null,
"defaultBlock": "latest",
//below the empty Methods attribute
"methods": {},
"events": {},
"_address": null,
"_jsonInterface": [
{
"constant": true,
"inputs": [],
"name": "getaltura",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xec1e5e46"
},
{
"constant": true,
"inputs": [],
"name": "getcircunferencia",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xd47dae09"
},
{
"constant": true,
"inputs": [],
"name": "getfumante",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x5655b1b5"
},
{
"constant": true,
"inputs": [],
"name": "getidade",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xd193ad65"
},
{
"constant": true,
"inputs": [],
"name": "getpeso",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0x81cbdaeb"
},
{
"constant": true,
"inputs": [],
"name": "getsaude",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function",
"signature": "0xb68059b2"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "altura",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "peso",
"type": "uint256"
}
],
"name": "setDados",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0xe892da6b"
},
{
"constant": false,
"inputs": [
{
"internalType": "uint256",
"name": "circunferencia",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "idade",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "saude",
"type": "uint256"
},
{
"internalType": "bool",
"name": "fumante",
"type": "bool"
}
],
"name": "setDesempenhoVida",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function",
"signature": "0x79cc1968"
}
]
}
}
As you can see the Methods attribute is empty. I want to point out that the rest of the contract instance is apparently normal and I have already tested this same way of doing a contract instance under other circumstances and have been successful.
Here is the smart contract that originated the eth.contract instance.
pragma solidity ^0.5.11;
contract ProntuarioHistorico2 {
struct Dados {
uint altura;
uint peso;
}
struct DesempenhoVida {
uint circunferencia;
uint idade;
uint saude;
bool fumante;
}
mapping (address => Dados) register_Dados;
mapping (address => DesempenhoVida) register_DesempenhoVida;
function setDados(uint altura, uint peso) public {
register_Dados[msg.sender] = Dados({
altura: altura,
peso: peso
});
}
function getaltura() public view returns(uint) {
return register_Dados[msg.sender].altura;
}
function getpeso() public view returns(uint) {
return register_Dados[msg.sender].peso;
}
function setDesempenhoVida(uint circunferencia, uint idade, uint saude, bool fumante) public {
register_DesempenhoVida[msg.sender] = DesempenhoVida({
circunferencia: circunferencia,
idade: idade,
saude: saude,
fumante: fumante
});
}
function getcircunferencia() public view returns(uint) {
return register_DesempenhoVida[msg.sender].circunferencia;
}
function getidade() public view returns(uint) {
return register_DesempenhoVida[msg.sender].idade;
}
function getsaude() public view returns(uint) {
return register_DesempenhoVida[msg.sender].saude;
}
function getfumante() public view returns(bool) {
return register_DesempenhoVida[msg.sender].fumante;
}
}
I know this is a big issue and it can be hard work, but I am immensely grateful for any help, please if anyone knows how to solve this problem or what I am doing wrong pronounces it.