aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libdevcore/CommonData.cpp25
-rw-r--r--libdevcore/CommonData.h4
-rw-r--r--libsolidity/analysis/TypeChecker.cpp8
-rw-r--r--libsolidity/ast/AST.cpp6
-rw-r--r--libsolidity/ast/AST.h2
6 files changed, 32 insertions, 14 deletions
diff --git a/Changelog.md b/Changelog.md
index 45521f3e..2487b87c 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -2,6 +2,7 @@
Features:
* Syntax Checker: Turn the usage of ``callcode`` into an error as experimental 0.5.0 feature.
+ * Type Checker: Improve address checksum warning.
* Type Checker: More detailed errors for invalid array lengths (such as division by zero).
Bugfixes:
diff --git a/libdevcore/CommonData.cpp b/libdevcore/CommonData.cpp
index db11e61c..85ad685b 100644
--- a/libdevcore/CommonData.cpp
+++ b/libdevcore/CommonData.cpp
@@ -86,20 +86,23 @@ bool dev::passesAddressChecksum(string const& _str, bool _strict)
))
return true;
+ return _str == dev::getChecksummedAddress(_str);
+}
+
+string dev::getChecksummedAddress(string const& _addr)
+{
+ string s = _addr.substr(0, 2) == "0x" ? _addr.substr(2) : _addr;
h256 hash = keccak256(boost::algorithm::to_lower_copy(s, std::locale::classic()));
- for (size_t i = 0; i < 40; ++i)
+ string ret = "0x";
+
+ for (size_t i = 0; i < s.length(); ++i)
{
char addressCharacter = s[i];
- bool lowerCase;
- if ('a' <= addressCharacter && addressCharacter <= 'f')
- lowerCase = true;
- else if ('A' <= addressCharacter && addressCharacter <= 'F')
- lowerCase = false;
- else
- continue;
unsigned nibble = (unsigned(hash[i / 2]) >> (4 * (1 - (i % 2)))) & 0xf;
- if ((nibble >= 8) == lowerCase)
- return false;
+ if (nibble >= 8)
+ ret += toupper(addressCharacter);
+ else
+ ret += tolower(addressCharacter);
}
- return true;
+ return ret;
}
diff --git a/libdevcore/CommonData.h b/libdevcore/CommonData.h
index 765707f8..e76a0949 100644
--- a/libdevcore/CommonData.h
+++ b/libdevcore/CommonData.h
@@ -209,4 +209,8 @@ bool contains(T const& _t, V const& _v)
/// are considered valid.
bool passesAddressChecksum(std::string const& _str, bool _strict);
+/// @returns the checksummed version of an address
+/// @param hex strings that look like an address
+std::string getChecksummedAddress(std::string const& _addr);
+
}
diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp
index 746e762e..fee60797 100644
--- a/libsolidity/analysis/TypeChecker.cpp
+++ b/libsolidity/analysis/TypeChecker.cpp
@@ -1122,7 +1122,7 @@ bool TypeChecker::visit(VariableDeclarationStatement const& _statement)
var.annotation().type->toString() +
". Try converting to type " +
valueComponentType->mobileType()->toString() +
- " or use an explicit conversion."
+ " or use an explicit conversion."
);
else
m_errorReporter.typeError(
@@ -1320,7 +1320,7 @@ bool TypeChecker::visit(TupleExpression const& _tuple)
_tuple.annotation().isPure = isPure;
if (_tuple.isInlineArray())
{
- if (!inlineArrayType)
+ if (!inlineArrayType)
m_errorReporter.fatalTypeError(_tuple.location(), "Unable to deduce common type for array elements.");
_tuple.annotation().type = make_shared<ArrayType>(DataLocation::Memory, inlineArrayType, types.size());
}
@@ -2000,7 +2000,9 @@ void TypeChecker::endVisit(Literal const& _literal)
m_errorReporter.warning(
_literal.location(),
"This looks like an address but has an invalid checksum. "
- "If this is not used as an address, please prepend '00'."
+ "If this is not used as an address, please prepend '00'. "
+ "Correct checksummed address: '" + _literal.getChecksummedAddress() + "'. "
+ "For more information please see https://solidity.readthedocs.io/en/develop/types.html#address-literals"
);
}
if (!_literal.annotation().type)
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 1048b610..4911f161 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -583,3 +583,9 @@ bool Literal::passesAddressChecksum() const
solAssert(isHexNumber(), "Expected hex number");
return dev::passesAddressChecksum(value(), true);
}
+
+std::string Literal::getChecksummedAddress() const
+{
+ solAssert(isHexNumber(), "Expected hex number");
+ return dev::getChecksummedAddress(value());
+}
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 733e7c78..5d6763ca 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -1613,6 +1613,8 @@ public:
bool looksLikeAddress() const;
/// @returns true if it passes the address checksum test.
bool passesAddressChecksum() const;
+ /// @returns the checksummed version of an address
+ std::string getChecksummedAddress() const;
private:
Token::Value m_token;