function createPair(address tokenA, address tokenB) external returns (address pair) {
require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'UniswapV2: ZERO_ADDRESS');
require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient
bytes memory bytecode = type(UniswapV2Pair).creationCode;
bytes32 salt = keccak256(abi.encodePacked(token0, token1));
assembly {
pair := create2(0, add(bytecode, 32), mload(bytecode), salt)
}
IUniswapV2Pair(pair).initialize(token0, token1);
getPair[token0][token1] = pair;
getPair[token1][token0] = pair; // populate mapping in the reverse direction
allPairs.push(pair);
emit PairCreated(token0, token1, pair, allPairs.length);
}我无法理解这一行代码是做什么的。将tokenA与地址类型的tokenB进行了比较。任何更多的解释都会很有帮助。(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
提前谢谢!
发布于 2021-11-08 11:11:12
如果您要求三元操作符做什么,则它等价于一个更紧凑(且不太明显)的If /else语句。
condition ? do_that_if_condition_is_true : do_that_if_condition_is_false;在您的特定代码段中,它用于在创建令牌对之前以特定方式排序地址。排序确保第一个令牌地址的数目低于第二个令牌地址(您的地址只是本质上是整数的十六进制表示,您可以进行比较)。
使用tokenA = address(100)和tokenB = address(50)
其中:结对总是等于(token1,token2)。
这本质上就是这一行所做的:
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);鉴于此:
require(tokenA != tokenB, 'UniswapV2: IDENTICAL_ADDRESSES');)保证排序为给定对提供唯一标识符。
最后,只要进行一次简单的检查,就足以验证这一对是否已经存在:
require(getPair[token0][token1] == address(0), 'UniswapV2: PAIR_EXISTS'); // single check is sufficient如果没有,就可以创建它。
发布于 2021-11-08 11:06:09
Uniswap v2确保每对令牌只有一个池。也就是说,如果已经存在带有令牌的池(A,B),则不可能按照不同的顺序创建具有相同令牌的新池:(B,A)。
Uniswap确保这一点的方法是始终根据其契约地址对令牌进行排序。这一行确保无论tokenA和tokenB的地址是什么,token0的地址总是比token1的地址小:
(address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);它可以这样改写:
address token0;
address token1;
if (tokenA < tokenB) {
token0 = tokenA;
token1 = tokenB;
} else {
token0 = tokenB;
token1 = tokenA;
}发布于 2022-11-21 07:37:13
上面的答案中给出的类比是,它将产生一个唯一的标识符,我们可以将它与对进行比较,看看它是否已经存在,这不是我们为什么要这样做的原因。
我附上了混音的截图,您可以看到,只要更改order,盐分就会改变,从而影响合同地址。


在UniswapV2Library中,您可以看到这两个函数通过sortTokens函数对地址进行排序,并在生成契约地址的pairFor函数中使用它,而不是进行外部调用。
这意味着,当输入和顺序相同时,我们必须确保始终生成相同的地址。
// returns sorted token addresses, used to handle return values from pairs sorted in this order
function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) {
require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES');
(token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS');
}
// calculates the CREATE2 address for a pair without making any external calls
function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
(address token0, address token1) = sortTokens(tokenA, tokenB);
pair = address(uint(keccak256(abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encodePacked(token0, token1)),
hex'e18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303' // init code hash
))));
}https://ethereum.stackexchange.com/questions/113113
复制相似问题