No, it doesn't. As a general rule of Ruby, if two things look alike, you can bet that there is a subtle difference between them, which makes each of them unique and necessary.
{ and } do not always stand in the role of block delimiters. When they do not stand in the role of block delimiters (such as when constructing hashes, { a: 1, b: 2 }), they cannot be replaced by do ... end. But when the curly braces do delimit a block, they can almost always be replaced by do ... end. But beware, because sometimes this can change the meaning of your statement. This is because { ... } have higher precedence, they bind tighter than do ... end:
puts [ 1, 2, 3 ].map { |e| e + 1 }         # { ... } bind with #map method
2
3
4
#=> nil
puts [ 1, 2, 3 ].map do |e| e + 1 end      # do ... end bind with #puts method
#<Enumerator:0x0000010a06d140>
#=> nil
As for the opposite situation, do ... end in the role of block delimiters cannot always be replaced by curly braces.
[ 1, 2, 3 ].each_with_object [] do |e, obj| obj << e.to_s end  # is possible
[ 1, 2, 3 ].each_with_object [] { |e, obj| obj << e.to_s }   # invalid syntax
In this case, you would have to parenthesize the ordered argument:
[ 1, 2, 3 ].each_with_object( [] ) { |e, obj| obj << e.to_s }  # valid with ( )
The consequence of these syntactic rules is that you can write this:
[ 1, 2, 3 ].each_with_object [ nil ].map { 42 } do |e, o| o << e end
#=> [ 42, 1, 2, 3 ]
And the above also demonstrates the case where {} are not replaceable by do/end:
[ 1, 2, 3 ].each_with_object [ nil ].map do 42 end do |e, o| o << e end
#=> SyntaxError
Lambda syntax with -> differs slightly in that it equally accepts both:
foo = -> x do x + 42 end  # valid
foo = -> x { x + 42 }     # also valid
Furthermore, do and end themselves do not always delimit a block. In particular, this
for x in [ 1, 2, 3 ] do
  puts x
end
and this
x = 3
while x > 0 do
  x -= 1
end
and this
x = 3
until x == 0 do
  x -= 1
end
superficially contains do ... end keywords, but there is no real block between them. The code inside them does not introduce a new scope, it is just syntax used to repeat a few statements. Curly braces cannot be used here, and the syntax could be written without do, such as:
for x in [ 1, 2, 3 ]
  puts x
end
# same for while and until
For the cases where {...} and do...end delimiters are interchangeable, the choice which ones to use is a matter of programming style, and is extensively discussed in another question (from whose accepted answer I took one of my examples here). My personal preference in such case is to emphasize readability over rigid rules.