函数gas要求高:无限
Gas requirement of function high: infinite
下面是我的智能合约。当我将其放入 remix 时,我会收到有关以下每个功能的警告。
函数的 gas 需求 MedicalRecord.addNote(bytes32,bytes32) 高:无限。
函数 MedicalRecord.getDoctorsNames() 的气体需求量高:无限。
函数 MedicalRecord.getNotes() 的气体需求高:无限。
函数 MedicalRecord.giveDoctorAccess(address,bytes32) 的 gas 需求高:无限。
pragma solidity ^0.4.17;
contract MedicalRecord {
struct Doctor {
bytes32 name;
uint id;
}
struct Note {
bytes32 title;
bytes32 note;
}
address public patient;
uint private doctorId;
bytes32[] public doctorsNames;
Note[] notes;
mapping (address => Doctor) private doctors;
modifier onlypatient {
require(msg.sender == patient);
_;
}
modifier isCurrentDoctor {
require(!(doctors[msg.sender].id < doctorId));
_;
}
function MedicalRecord() public {
patient = msg.sender;
doctorId = 0;
}
function giveDoctorAccess(address drAddress, bytes32 name)
public
onlypatient
returns (bytes32)
{
doctors[drAddress] = Doctor (name, doctorId);
doctorId++;
doctorsNames.push(name);
return (name);
}
function getNotes()
view
public
isCurrentDoctor
returns (bytes32[], bytes32[])
{
bytes32[] memory titles = new bytes32[](notes.length);
bytes32[] memory noteTexts = new bytes32[](notes.length);
for (uint i = 0; i < notes.length; i++) {
Note storage snote = notes[i];
titles[i] = snote.title;
noteTexts[i] = snote.note;
}
return (titles, noteTexts);
}
function getDoctorsNames() view public returns (bytes32[]) {
return doctorsNames;
}
function addNote(bytes32 title, bytes32 note) public isCurrentDoctor
{
notes.push(Note({title: title, note:note}));
}
}
谁能告诉我如何改进它?
任何对动态数组的引用都会导致无限气体警告。这并不一定意味着你做错了什么。
从优化规模来看,您可以做几件小事,但大多数不会显着改变您的气体消耗。例如,我认为不需要存储单独的 doctorNames
数组,因为您已经将它们保存在 Doctor
结构中。此外,一般来说,像在 getNotes()
中那样遍历可能无限的项目数组并不是一个好主意。通常,最好有一个 returns 数组长度的函数,然后调用一个单独的函数来获取传入索引的注释(换句话说,在您的客户端中执行循环)。但即使在这里,您的用例似乎也不会产生大量注释。
您最大的成本将是您的合同被绑定到一个病人身上。合同部署非常昂贵。在这里,您将为系统中的每个患者部署一个合同(可能每个患者有多个合同,因为它是医疗记录?)。我希望将所有内容都推入结构中,并为所有 patients/medical 记录签订一份合同。可能每位患者一份合同,具体取决于整体业务案例(即使考虑到这一点,我想我会先探索每位医生一份合同)。但是,当然不是每个病历的合同。
下面是我的智能合约。当我将其放入 remix 时,我会收到有关以下每个功能的警告。
函数的 gas 需求 MedicalRecord.addNote(bytes32,bytes32) 高:无限。
函数 MedicalRecord.getDoctorsNames() 的气体需求量高:无限。
函数 MedicalRecord.getNotes() 的气体需求高:无限。
函数 MedicalRecord.giveDoctorAccess(address,bytes32) 的 gas 需求高:无限。
pragma solidity ^0.4.17;
contract MedicalRecord {
struct Doctor {
bytes32 name;
uint id;
}
struct Note {
bytes32 title;
bytes32 note;
}
address public patient;
uint private doctorId;
bytes32[] public doctorsNames;
Note[] notes;
mapping (address => Doctor) private doctors;
modifier onlypatient {
require(msg.sender == patient);
_;
}
modifier isCurrentDoctor {
require(!(doctors[msg.sender].id < doctorId));
_;
}
function MedicalRecord() public {
patient = msg.sender;
doctorId = 0;
}
function giveDoctorAccess(address drAddress, bytes32 name)
public
onlypatient
returns (bytes32)
{
doctors[drAddress] = Doctor (name, doctorId);
doctorId++;
doctorsNames.push(name);
return (name);
}
function getNotes()
view
public
isCurrentDoctor
returns (bytes32[], bytes32[])
{
bytes32[] memory titles = new bytes32[](notes.length);
bytes32[] memory noteTexts = new bytes32[](notes.length);
for (uint i = 0; i < notes.length; i++) {
Note storage snote = notes[i];
titles[i] = snote.title;
noteTexts[i] = snote.note;
}
return (titles, noteTexts);
}
function getDoctorsNames() view public returns (bytes32[]) {
return doctorsNames;
}
function addNote(bytes32 title, bytes32 note) public isCurrentDoctor
{
notes.push(Note({title: title, note:note}));
}
}
谁能告诉我如何改进它?
任何对动态数组的引用都会导致无限气体警告。这并不一定意味着你做错了什么。
从优化规模来看,您可以做几件小事,但大多数不会显着改变您的气体消耗。例如,我认为不需要存储单独的 doctorNames
数组,因为您已经将它们保存在 Doctor
结构中。此外,一般来说,像在 getNotes()
中那样遍历可能无限的项目数组并不是一个好主意。通常,最好有一个 returns 数组长度的函数,然后调用一个单独的函数来获取传入索引的注释(换句话说,在您的客户端中执行循环)。但即使在这里,您的用例似乎也不会产生大量注释。
您最大的成本将是您的合同被绑定到一个病人身上。合同部署非常昂贵。在这里,您将为系统中的每个患者部署一个合同(可能每个患者有多个合同,因为它是医疗记录?)。我希望将所有内容都推入结构中,并为所有 patients/medical 记录签订一份合同。可能每位患者一份合同,具体取决于整体业务案例(即使考虑到这一点,我想我会先探索每位医生一份合同)。但是,当然不是每个病历的合同。