智能合约:如果我调用一个使用 public 变量的函数,是否可以通过调用其他用户的函数来修改它?

Smart contracts: If i call a function that is using a public variable, can it be modified by the call of a function of other user?

我正在制作一个去中心化的众筹智能合约以学习更多关于这门语言的知识。

合约能够在一个映射中存储许多众筹项目,如下所示

struct CrowdFundingProject{
    address author,
    string description,
    string title,
    uint goal,
    bool exists
}
mapping(uint, CrowdFundingProject) public projects;
uint lastProject = 0;

映射的键是一个自动递增的数字。当您创建项目时,它看起来像这样:

function createProject(string title, string desc, uint goal) public{
    CrowdFundingProject newProject;
    newProject.author = msg.sender;
    newProject.title = title;
    newProject.description = desc;
    newProject.goal = goal;
    newProject.exists = true;
    lastProject += 1;
    projects[lastProject] = newProject;
}

但我相信这可能会导致问题,例如,如果用户 A 运行 函数 createProject 并且恰好在 EVM 正在执行时 lastProject += 1; 用户 B 也运行该函数,使得如果lastProject 等于 100 现在是 101 同时 projects[lastProject] = newProject; 没有为用户 A 完成执行,两者都会有一个 ID 为 101 的项目。这将覆盖用户 A 的项目把那个留给用户 B。

这是正确的吗?如果是这样,我的另一种方法不是直接将项目添加为 project[lastProject] 而是做类似

的事情会更好
 lastProject += 1;
 uint myProjectsId = lastProject - 1;
 projects[myProjectsId] =  newProject;

我不知道这种方法是否会导致任何类型的错误,或者是否有可能出现覆盖错误,所以我想确定一下:

会不会出现ID重叠这样的错误? 如果是这样:我提出的第二种方法会带来任何奇怪的行为吗?

if user A ran the function createProject and just when the EVM is executing lastProject += 1; User B runs the function too

EVM 以串行而非并行方式执行交易。

每个区块中的交易按照区块矿工选择的方式排序。大多数矿工只是简单地从最大 gasPrice 到最小排序。

所以根据提供的代码,没有办法覆盖 projects 密钥,即使两个单独的交易在同一个块中执行 createProject() 函数:具有较大 [=10] 的交易=] 将获得项目 ID 100,另一个将在毫秒后执行并获得项目 ID 101。


有一种称为抢先交易的攻击向量,与根据 gasPrice 对区块中的交易进行排序有关。阅读它可能会有用,例如,有一篇很棒的 article 描述了基础知识。

您的代码容易受到此向量的攻击,但这实际上无关紧要,因为攻击者只能先行运行某人并窃取他们想要的项目 ID(使原始项目创建者的 ID 高 1) .领先者通常的激励措施是窃取 ETH 和代币(并且您的代码未显示使用 ETH 或代币)。