
49万USDT钱包资产被转走之到底是不是朋友干的?
话题背景wu351256@discord 有谁知道我的代币为什么会在我不知情的情况下下被转走,我查记录上面说是触发了什么智能合约。我是新手有大神带我理解一下嘛? 如果是触发了什么智能合约怎么找到这个合约并且解除合约进入正题@bmlcwenwu 是不是点了什么钓鱼链接?赶快去解除授权 @42069Imtoken里边有教程,先解除授权 @夜与昼 这种币被盗了,报警说不立案,imtoken客服说报警,投诉无门,欲哭无泪 @42069 国内加密货币属于非法,警察不立案。 @夜与昼 对啊,国内,我被盗了49万usdt夜与昼 @42069 这么多U,没想到用冷钱包吗 @夜与昼 我最后一次转账用我朋友的id下载的app,现在就是不知道会不会是他盗的 @42069 什么app? @夜与昼 Imtoken钱包 @42069 不是假的吧 @夜与昼 用他的id后,商城里下载的,登录进去给他转了一笔钱,一个星期后钱包被盗 @42069 登录之后退出id了吗?只是商城登录id没事 夜与昼登录后退出了,登录的时候还双重认证了, *[2:39 PM]*Icloud就会自动登陆 *[2:39 PM]*Iclou...
Etherscan事务交易详细分类
TransferERC21https://cn.etherscan.com/tx/0xc261caa5556785d46fbf5f715f4e5686288304a5a510d34336d763b060dc37b6Swap案例1: https://cn.etherscan.com/tx/0xf09f3b3dcd29552dac6fd14040bb457f3f462ab497dd4a885fcf1bcc026f10ff https://cn.etherscan.com/tx/0x23fdb4a895877af5d2091d541d05f6ae874267c8d82e73bb7f186d8839781c92ApproveERC20ERC721ERC1159https://cn.etherscan.com/tx/0x00ff492f7c93e50b47c1c341d935e5d5cac201455d7d7f8a491fd5f0a7d93746MintERC721MethodID: 0xa0712d68Function: mint(uint256 _mintAmount) MethodI...

以太坊签名验签原理揭秘
签名三大作用讨论密码学中的签名时,我们其实是在讨论所有权、有效性和完整性证明。举例来说,这些签名可以用来:证明你拥有地址的私钥(即认证功能);确保信息(例如,邮件)没有被篡改;验证你下载的 文件是合法有效的。签名基础原理:基于数学公式输入:一个输入消息、一个私钥和一个(通常情况下是秘密的)随机数,就可以得到一串数字作为输出值,也就是签名。 输出:使用另一个数学公式可以进行反向计算,在不知道私钥和随机数的情况下进行验证(译者注:即验证该签名是否出自跟某个公钥对应的私钥)。 这类算法有很多,如 RSA 和 AES,但是以太坊(和比特币)采用的都是椭圆曲线数字签名算法(ECDSA)。请注意,ECDSA 只是签名算法。与 RSA 和 AES 不同,这种算法不能用于加密。以太坊采用的是 secp256k1曲线。 签名方案由哈希算法和签名算法组成。以太坊选择的签名算法是secp256k1,哈希算法选择了keccak256,这是一个从字节串。不可逆计算通过椭圆曲线点乘算法(elliptic curve point manipulation),我们可以使用私钥计算出一个不可逆向计算的值(译者注:...
The infinite past has the present as its destination, and the infinite future has the present as its origin.

49万USDT钱包资产被转走之到底是不是朋友干的?
话题背景wu351256@discord 有谁知道我的代币为什么会在我不知情的情况下下被转走,我查记录上面说是触发了什么智能合约。我是新手有大神带我理解一下嘛? 如果是触发了什么智能合约怎么找到这个合约并且解除合约进入正题@bmlcwenwu 是不是点了什么钓鱼链接?赶快去解除授权 @42069Imtoken里边有教程,先解除授权 @夜与昼 这种币被盗了,报警说不立案,imtoken客服说报警,投诉无门,欲哭无泪 @42069 国内加密货币属于非法,警察不立案。 @夜与昼 对啊,国内,我被盗了49万usdt夜与昼 @42069 这么多U,没想到用冷钱包吗 @夜与昼 我最后一次转账用我朋友的id下载的app,现在就是不知道会不会是他盗的 @42069 什么app? @夜与昼 Imtoken钱包 @42069 不是假的吧 @夜与昼 用他的id后,商城里下载的,登录进去给他转了一笔钱,一个星期后钱包被盗 @42069 登录之后退出id了吗?只是商城登录id没事 夜与昼登录后退出了,登录的时候还双重认证了, *[2:39 PM]*Icloud就会自动登陆 *[2:39 PM]*Iclou...
Etherscan事务交易详细分类
TransferERC21https://cn.etherscan.com/tx/0xc261caa5556785d46fbf5f715f4e5686288304a5a510d34336d763b060dc37b6Swap案例1: https://cn.etherscan.com/tx/0xf09f3b3dcd29552dac6fd14040bb457f3f462ab497dd4a885fcf1bcc026f10ff https://cn.etherscan.com/tx/0x23fdb4a895877af5d2091d541d05f6ae874267c8d82e73bb7f186d8839781c92ApproveERC20ERC721ERC1159https://cn.etherscan.com/tx/0x00ff492f7c93e50b47c1c341d935e5d5cac201455d7d7f8a491fd5f0a7d93746MintERC721MethodID: 0xa0712d68Function: mint(uint256 _mintAmount) MethodI...

以太坊签名验签原理揭秘
签名三大作用讨论密码学中的签名时,我们其实是在讨论所有权、有效性和完整性证明。举例来说,这些签名可以用来:证明你拥有地址的私钥(即认证功能);确保信息(例如,邮件)没有被篡改;验证你下载的 文件是合法有效的。签名基础原理:基于数学公式输入:一个输入消息、一个私钥和一个(通常情况下是秘密的)随机数,就可以得到一串数字作为输出值,也就是签名。 输出:使用另一个数学公式可以进行反向计算,在不知道私钥和随机数的情况下进行验证(译者注:即验证该签名是否出自跟某个公钥对应的私钥)。 这类算法有很多,如 RSA 和 AES,但是以太坊(和比特币)采用的都是椭圆曲线数字签名算法(ECDSA)。请注意,ECDSA 只是签名算法。与 RSA 和 AES 不同,这种算法不能用于加密。以太坊采用的是 secp256k1曲线。 签名方案由哈希算法和签名算法组成。以太坊选择的签名算法是secp256k1,哈希算法选择了keccak256,这是一个从字节串。不可逆计算通过椭圆曲线点乘算法(elliptic curve point manipulation),我们可以使用私钥计算出一个不可逆向计算的值(译者注:...
The infinite past has the present as its destination, and the infinite future has the present as its origin.

Subscribe to Renaissance Labs

Subscribe to Renaissance Labs
Share Dialog
Share Dialog
<100 subscribers
<100 subscribers


创建合约的语法:
new 合约名();
示例:
contract A {}
contract B {
function test() public {
A a = new A();
}
}
创建合约实例的时候,默认会调用构造函数,并执行构造函数中的代码。如果没有定义构造函数,EVM编译器会自动生成一个默认的构造函数。如果构造函数指定了参数,那么创建合约实例时候需要传入相同数量的实参。
contract A {
int num;
constructor(int _num) public {
num = _num;
}
}
contract B {
function test() public {
A a = new A(10);
}
}
注意:合约构造函数是可选的。solidity不支持构造函数的重载,也就是一个合约最多只有一个构造函数。
一个合约可以继承另外一个合约,也可以同时继承多个合约
contract A {}
contract B is A {}
如果同时继承了多个父合约,最远的派生函数会被调用。
contract C is A, B {}
contract SimpleContract {
function test() public returns(uint) {
C c = new C();
c.a(); // 20
c.f(); // 20
}
}
上面合约C同时继承了A和B,因为B合约比A合约距离C合约远,所以在test函数中调用父合约状态变量和函数,实际调用的是B合约。
父合约的函数可以被派生合约中具有相同名称、相同参数的函数重载。如果派生合约的重载函数的返回值类型或数量不相同,会导致错误。
如果父合约构造函数带参数,那么可以在派生合约声明时候指定参数,或者也可以在构造函数位置以修饰器方式提供。
contract A {
int num;
constructor(int _num) public {
num = _num;
}
}
contract B is A {}
contract B is A(10) {}
contract B is A {
constructor() public A(10) {}
}
如果一个派生合约没有指定所有父合约的构造函数参数,那么该合约是一个抽象合约。
contract A {
uint a;
constructor(uint _a) internal {
a = _a;
}
}
contract B is A {}
contract SimpleContract {
function test() public {
//B a = new B();
}
}
因为合约B继承合约A时候,没有指定构造函数参数,因此合约B是一个抽象合约。抽象合约不能够实例化,因此上面test函数中注释代码会报错。
另外,如果一个合约包含未实现的函数,那么该合约也是一个抽象合约。
contract A {
function test() public;
}
接口主要用于规范合约的实现,其定义格式为:
定义接口使用
interface关键字。接口里面只能够声明函数,不能定义状态变量和构造函数,也不能够对函数提供实现。
interface InterfaceA {
function f() external;
}
上面接口函数f()必须要使用external修饰符。与Java不同,solidity接口之间无法继承。

一个合约可以继承多个接口。
interface InterfaceA {}
interface InterfaceB {}
interface Impl is InterfaceA, InterfaceB {}
如果一个合约没有实现接口里面的所有函数,那么该合约是一个抽象合约。
👉抽象合约与接口的相同点和不同点?
1)抽象合约可以定义状态变量和构造函数,而接口不可以;
2)抽象合约中的函数可以不实现,也可以实现,而接口中只能包含未实现的函数;
3)抽象合约中的函数可以使用任意修饰符,但接口中函数只能使用external修饰符;
4)抽象合约可以继承其他合约或接口,而接口不能;
5)抽象合约和接口都不能实例化;
6)抽象合约和接口都可以声明结构体和枚举;
库合约不同于一般合约,它更像Java里的工具类,负责为其他合约提供有用的工具函数。
定义语法:
library 库合约 {}
库合约可以定义结构体、枚举,也可以声明状态变量,但是状态变量必须是常量。
像一般函数调用一样,库合约中的成员可以通过库合约.成员方式访问。
library Utils {
function sum(uint a, uint b) public pure returns(uint) {
return a + b;
}
}
library SimpleContract {
function test() public pure {
uint result = Utils.sum(10, 20);
}
}
如果在合约中包含了库合约,那么部署合约时候,EVM会自动将库合约代码包含进来,无需额外部署库合约。
除了上面调用方式以外,还可以通过using...for语法访问库合约里面的函数。该语法运行将库合约中的函数附加到任意类型上,从而实现类似原生函数调用的效果。
library Utils {
function get(int[] storage self, uint index) internal view returns(int) {
require(index >= 0);
return self[index];
}
function get(mapping(address => uint128) storage self) internal view returns(uint128) {
require(msg.sender > address(0));
return self[msg.sender];
}
}
contract SimpleContract {
int[] ids;
mapping(address => uint128) balances;
using Utils for int[];
using Utils for mapping(address => uint128);
function test() public view {
int id = ids.get(0);
uint128 bal = balances.get();
}
}
上面库合约定义了两个重载方法。当使用using..for语法访问库合约时候,第一个参数为对应类型的状态变量。
上面代码通过using...for语法,将库合约绑定到uint[]和mapping(address => uint128)类型。因此,该合约中所有uint[]和mapping(address => uint128)类型的变量都可以库函数,这时候库函数的第一个参数引用了调用该函数的变量。
事件使得开发者可以访问EVM的日志系统,帮助开发者了解智能合约运行过程的状态信息。开发者可以在dapp中监听solidity事件,当智能合约中触发了某个事件,EVM的日志系统会反过来调用dapp中定义的事件回调函数,从而在回调函数中将日志信息打印出来。
记录在区块链上的日志信息可以被外部检索出来。solidity规定一个事件里面最多有3个参数可以设置为indexed,表示用户可以通过该参数对搜索结果进行过滤。所有非indexed参数将保存在日志的数据部分,而indexed参数不会被保存。
contract SimpleContract {
event LogSave(
address indexed _addr,
uint _value
);
function saveMoney() public payable {
if (msg.value <= 100 wei) {
emit LogSave(msg.sender, msg.value);
}
}
}
上面合约定义了一个LogSave事件,其中第一个参数是可索引参数。在saveMoney函数中,判断如果msg.value小于等于100 wei,则触发LogSave事件。
创建合约的语法:
new 合约名();
示例:
contract A {}
contract B {
function test() public {
A a = new A();
}
}
创建合约实例的时候,默认会调用构造函数,并执行构造函数中的代码。如果没有定义构造函数,EVM编译器会自动生成一个默认的构造函数。如果构造函数指定了参数,那么创建合约实例时候需要传入相同数量的实参。
contract A {
int num;
constructor(int _num) public {
num = _num;
}
}
contract B {
function test() public {
A a = new A(10);
}
}
注意:合约构造函数是可选的。solidity不支持构造函数的重载,也就是一个合约最多只有一个构造函数。
一个合约可以继承另外一个合约,也可以同时继承多个合约
contract A {}
contract B is A {}
如果同时继承了多个父合约,最远的派生函数会被调用。
contract C is A, B {}
contract SimpleContract {
function test() public returns(uint) {
C c = new C();
c.a(); // 20
c.f(); // 20
}
}
上面合约C同时继承了A和B,因为B合约比A合约距离C合约远,所以在test函数中调用父合约状态变量和函数,实际调用的是B合约。
父合约的函数可以被派生合约中具有相同名称、相同参数的函数重载。如果派生合约的重载函数的返回值类型或数量不相同,会导致错误。
如果父合约构造函数带参数,那么可以在派生合约声明时候指定参数,或者也可以在构造函数位置以修饰器方式提供。
contract A {
int num;
constructor(int _num) public {
num = _num;
}
}
contract B is A {}
contract B is A(10) {}
contract B is A {
constructor() public A(10) {}
}
如果一个派生合约没有指定所有父合约的构造函数参数,那么该合约是一个抽象合约。
contract A {
uint a;
constructor(uint _a) internal {
a = _a;
}
}
contract B is A {}
contract SimpleContract {
function test() public {
//B a = new B();
}
}
因为合约B继承合约A时候,没有指定构造函数参数,因此合约B是一个抽象合约。抽象合约不能够实例化,因此上面test函数中注释代码会报错。
另外,如果一个合约包含未实现的函数,那么该合约也是一个抽象合约。
contract A {
function test() public;
}
接口主要用于规范合约的实现,其定义格式为:
定义接口使用
interface关键字。接口里面只能够声明函数,不能定义状态变量和构造函数,也不能够对函数提供实现。
interface InterfaceA {
function f() external;
}
上面接口函数f()必须要使用external修饰符。与Java不同,solidity接口之间无法继承。

一个合约可以继承多个接口。
interface InterfaceA {}
interface InterfaceB {}
interface Impl is InterfaceA, InterfaceB {}
如果一个合约没有实现接口里面的所有函数,那么该合约是一个抽象合约。
👉抽象合约与接口的相同点和不同点?
1)抽象合约可以定义状态变量和构造函数,而接口不可以;
2)抽象合约中的函数可以不实现,也可以实现,而接口中只能包含未实现的函数;
3)抽象合约中的函数可以使用任意修饰符,但接口中函数只能使用external修饰符;
4)抽象合约可以继承其他合约或接口,而接口不能;
5)抽象合约和接口都不能实例化;
6)抽象合约和接口都可以声明结构体和枚举;
库合约不同于一般合约,它更像Java里的工具类,负责为其他合约提供有用的工具函数。
定义语法:
library 库合约 {}
库合约可以定义结构体、枚举,也可以声明状态变量,但是状态变量必须是常量。
像一般函数调用一样,库合约中的成员可以通过库合约.成员方式访问。
library Utils {
function sum(uint a, uint b) public pure returns(uint) {
return a + b;
}
}
library SimpleContract {
function test() public pure {
uint result = Utils.sum(10, 20);
}
}
如果在合约中包含了库合约,那么部署合约时候,EVM会自动将库合约代码包含进来,无需额外部署库合约。
除了上面调用方式以外,还可以通过using...for语法访问库合约里面的函数。该语法运行将库合约中的函数附加到任意类型上,从而实现类似原生函数调用的效果。
library Utils {
function get(int[] storage self, uint index) internal view returns(int) {
require(index >= 0);
return self[index];
}
function get(mapping(address => uint128) storage self) internal view returns(uint128) {
require(msg.sender > address(0));
return self[msg.sender];
}
}
contract SimpleContract {
int[] ids;
mapping(address => uint128) balances;
using Utils for int[];
using Utils for mapping(address => uint128);
function test() public view {
int id = ids.get(0);
uint128 bal = balances.get();
}
}
上面库合约定义了两个重载方法。当使用using..for语法访问库合约时候,第一个参数为对应类型的状态变量。
上面代码通过using...for语法,将库合约绑定到uint[]和mapping(address => uint128)类型。因此,该合约中所有uint[]和mapping(address => uint128)类型的变量都可以库函数,这时候库函数的第一个参数引用了调用该函数的变量。
事件使得开发者可以访问EVM的日志系统,帮助开发者了解智能合约运行过程的状态信息。开发者可以在dapp中监听solidity事件,当智能合约中触发了某个事件,EVM的日志系统会反过来调用dapp中定义的事件回调函数,从而在回调函数中将日志信息打印出来。
记录在区块链上的日志信息可以被外部检索出来。solidity规定一个事件里面最多有3个参数可以设置为indexed,表示用户可以通过该参数对搜索结果进行过滤。所有非indexed参数将保存在日志的数据部分,而indexed参数不会被保存。
contract SimpleContract {
event LogSave(
address indexed _addr,
uint _value
);
function saveMoney() public payable {
if (msg.value <= 100 wei) {
emit LogSave(msg.sender, msg.value);
}
}
}
上面合约定义了一个LogSave事件,其中第一个参数是可索引参数。在saveMoney函数中,判断如果msg.value小于等于100 wei,则触发LogSave事件。
No activity yet