0
votes

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.

1

1 Answers

0
votes

Your code works fine on my computer, methods field is correctly built. Try to upgrade your packages?

I am using solcjs with version 0.5.13 and web3 with version 1.2.4.