javascript - 地图如何在内存中初始化
问题描述
我刚开始写solidity,我有一些我找不到答案的问题。
当您声明这样的地图时:
struct UserAccount{
string name;
uint id;
}
mapping (address => UserAccount) public accounts;
那将如何初始化?还是用什么?
例如,访问
accounts[0x79d66c53ad6f1847288c0d06c01a2b38c38f15bc]
将返回一个 UserAccount 的实例?如果是,这意味着地图会为每个可能的地址创建一个 UserAccount 实例?这不是非常消耗内存吗?如果没有,那么你怎么能这样做:
accounts[_address].name = _name;
?
第二个问题:
我在合同中保留了作为所有者地址的引用,即创建合同的地址:
address public owner;
constructor() public {
owner = msg.sender;
}
在我调用这个函数之后:
uint userCount=0;
mapping (address => UserAccount) public accounts;
function createAccount(string _name, uint _id, address _address) onlyOwner() public {
UserAccount user;
user.name = _name;
user.id = _id;
accounts[_address] = user;
userCount += 1;
// accounts[_address].name = _name;
// accounts[_address].id = _id;
// userCount += 1;
emit UserCreated(_address, _id, _name);
}
modifier onlyOwner() {
require(msg.sender == owner);
_;
}
所有者地址发生变化。createAccount 函数中的注释行是这样做的方法,我知道,但我想了解它为什么不起作用。
为了澄清我的问题,我还将发布一个 js 测试。
beforeEach(async () => {
voting = await Voting.new({from: owner});
});
it("Should delete poll, as owner", async () =>{
var name = "Sandu";
console.log("LOCAL OWNER= " + owner);
console.log("OWNER BEFORE CREATE ACCOUNT FROM SOL= " + await voting.owner());
await voting.createAccount(name, 1, firstUser,{from:owner});
console.log("OWNER AFTER CREATE ACCOUNT FROM SOL= " + await voting.owner());
var pollName = "First Poll";
var endDateS="2018-08-11T10:20:30Z";
var endDate=new Date(endDateS)
await voting.createPoll(pollName, 1, endDate.getTime()/1000,{from:firstUser});
try{
await voting.deletePollById(1,{from: owner});
}catch(err){
console.log(err.message);
}
assert.notEqual(pollName, await voting.getPollById(1));
});
上面的测试打印了这个:
LOCAL OWNER= 0x79d66c53ad6f1847288c0d06c01a2b38c38f15bc //Owner that o have in my js file local, first address from the ganache accounts.
OWNER BEFORE CREATE ACCOUNT FROM SOL= 0x79d66c53ad6f1847288c0d06c01a2b38c38f15bc //The owner account from my contract before calling the function
OWNER AFTER CREATE ACCOUNT FROM SOL= 0x000000000000000000000000000000000000000a //The owner account from my contract after calling the function
我不明白为什么所有者的价值会发生变化,因为我没有在我的功能中触及它。
如果有人可以提供帮助,将不胜感激。再一次,我知道正确的方法,但我发布这个是为了了解我在做什么而不是完成工作。
解决方案
请不要在一个帖子中发布多个问题,因为这会导致问题过于宽泛而被关闭。
对于您的第一个问题,所有变量都有一个初始默认值。来自Solidity 文档:
映射可以看作是经过虚拟初始化的哈希表,使得每个可能的键都存在并映射到字节表示全为零的值:类型的默认值。
零值不使用存储。
对于您的第二个问题,您正在覆盖状态变量,因为您正在使用一个storage
应该使用变量的memory
变量。请参阅此处提供的答案:solidity 中的状态变量是什么?
推荐阅读
- python - 如何跳过范围循环中的元素?
- html - 两个选项之间的定义列表的自动样式
- django - 使用来自实例的值启动 Django modelformset?
- c# - WPF 无法为动态创建的用户控件设置数据上下文
- reactjs - 为什么这种语法对我试图创建的组件的箭头函数语法有效?
- react-hooks - 使用 React 钩子时的公共属性
- node.js - MySQL xdevapi 节点错误:SELF_SIGNED_CERT_IN_CHAIN
- java - “swagger-codegen-maven-plugin:3.0.0 或其依赖项之一无法解析”
- spring-mvc - 从控制器重定向到视图时,某些模型属性字段为空
- c++ - c ++ Postfix-Notation Evaluator使用堆栈